Как установить проверенную / непроверенную функциональность для таблицы Html в Reactjs

#javascript #html #reactjs

#javascript #HTML #reactjs

Вопрос:

У меня есть массив объектов Json (‘filteredUsers’ в приведенном ниже коде), и я сопоставляю их с таблицей html. Объект Json будет выглядеть как {id: xyz, имя: Dubov}

Приведенный ниже код будет отображать таблицу html с одним столбцом или в основном список. В каждой строке изначально будет указано имя пользователя и серый флажок (не отмечен) рядом с ним. Я хочу выбрать пользователей в таблице, и когда я выбираю или нажимаю на любой элемент в таблице, флажок должен стать зеленым (установлен).

             <table className="table table-sm">
              {this.state.filteredUsers amp;amp; (
                <tbody>
                  {this.state.filteredUsers.map((user) => (
                    <tr key={user.id}>
                      <td onClick={() => this.selectUser(user)}>
                        
                        <span>{user.name}</span>               //Name

                        <div className={user.selected? "checked-icon": "unchecked-icon"}>   //Checkmark icon
                           <span class="checkmark"> </span>
                         </div>

                      </td>
                    </tr>
                  ))}
                </tbody>
              )}
            </table>
 

Я попытался установить «выбранный» ключ для каждого объекта. Изначально у объекта нет ключа ‘selected’, поэтому он будет false (все непроверенные). Я установил метод onClick для строки ‘td’, который устанавливает ключ ‘selected’ для объекта и устанавливает для него значение true. Приведенная ниже функция вызывается onClick элемента td или таблицы.

   selectUser = (user) => {
    user.selected = !user.selected;
  };
 

Теперь проблема в том, что это будет работать, только если я повторно визуализирую страницу после каждого onClick ‘td’ или элемента таблицы. И я вынужден выполнить пустое setState или this.forcedUpdate() в методе selectUser, чтобы вызвать повторный рендеринг. Я читал в нескольких ответах, что принудительный рендеринг — это плохо.

Любые предложения или помощь будут высоко оценены. Даже полное изменение логики также подходит. Моя конечная цель — если я выберу элемент, серая галочка должна стать зеленой (отмечена), и если я снова нажму на нее, она должна стать серой (не отмечена). Аналогично для всех элементов. Оставьте часть CSS мне, но помогите мне с логикой. Спасибо.

Комментарии:

1. Возможно, перед тем, как поместить полученную полезную нагрузку в state ( filteredUsers ), вы могли бы использовать .map() и добавить selected поле для каждого пользователя с желаемым значением.

2. @Eyal C Значение выбранного поля продолжает меняться всякий раз, когда я нажимаю на элемент. Как я могу установить это заранее? Я хочу, чтобы проверенная-непроверенная функция работала в режиме реального времени.

3. Пожалуйста, проверьте мой ответ ниже

Ответ №1:

Как насчет чего-то подобного:

 const Users = () => {
  const [users, setUsers] = useState([])

  useEffect(() => {
    // Fetch users from the API when the component mounts
    api.getUsers().then((users) => {
      // Add a `selected` field to each user and store them in state
      setUsers(users.map((user) => ({ ...user, selected: true })))
    })
  }, [])

  const toggleUserSelected = (id) => {
    setUsers((oldUsers) =>
      oldUsers.map((user) =>
        user.id === id ? { ...user, selected: !user.selected } : user
      )
    )
  }

  return (
    <ul>
      {users.map((user) => (
        <li key={user.id} onClick={() => toggleUserSelected(user.id)}>
          <span>{user.name}</span>

          <div className={user.selected ? "checked-icon" : "unchecked-icon"}>
            <span class="checkmark" />
          </div>
        </li>
      ))}
    </ul>
  )
}
 

Я использовал для этого хуки, но принципы те же.

Комментарии:

1. Спасибо за ответ. Не могли бы вы написать эквивалент setState для хука setUsers. Я не очень хорошо знаком с концепциями hooks.

2. Эквивалент setUsers(newUsers) будет this.setState({ users: newUsers })

Ответ №2:

Похоже, это проблема состояния. При обновлении данных в вашем компоненте react вам нужно убедиться, что это происходит одним из двух способов:

  1. Данные обновляются компонентом, расположенным выше в дереве, а затем передаются этому компоненту через props.
    • это приведет к повторному отображению вашего компонента с новыми реквизитами и данными, обновляя свойство «checked» в вашем HTML.

В вашем случае, похоже, вы используете этот второй способ:

  1. Данные хранятся в состоянии компонента. Затем, когда вам нужно обновить данные, вы должны сделать что-то вроде приведенного ниже.
 const targetUser = this.state.filteredUsers.find(user => user.id === targetId)
const updatedUser = { ...targetUser, selected: !targetUser.selected }

this.setState({ filteredUsers: [ ...this.state.filteredUsers, updatedUser ] })
 

Обновление вашего состояния таким образом вызовет обновление вашего компонента. Прямое изменение объекта состояния без использования setState не запускает обновление.

Пожалуйста, имейте в виду, что при обновлении объектов в состоянии компонента вам нужно будет передать новый полный объект setState , чтобы запустить обновление. Что-то подобное не будет работать: this.setState({ filteredUsers[1].selected: false });

Соответствующая документация

Комментарии:

1. Это выдает ошибку. «this.state.filteredUsers.map не является функцией» . Я не понимаю, как вы добавляете объект update user обратно в состояние.

2. Это потому, что я рассматривал filteredUsers как объект, когда он выглядит как массив. Ваша ошибка возникает позже в вашем коде, когда вы пытаетесь запустить .map функцию для вашего нового объекта, у которого нет этой функции. Я обновил свой ответ, чтобы он обрабатывался filteredUsers как массив `

3. этот метод снова добавляет тех же пользователей в массив с выбранным ключом. Нам нужен способ добавить выбранное свойство к существующему объекту user или заменить существующее на updateduser.

4. Я намеренно не предоставил точный код, необходимый для выполнения этой работы за вас. Мое решение разработано, чтобы помочь вам понять обновления состояния реакции, чтобы затем вы могли написать свой собственный код так, как это имеет для вас наибольший смысл. Обновление состояния — это то, что здесь требуется. Если используемый вами код неправильно обновляет состояние, пожалуйста, ознакомьтесь с соответствующей ссылкой на документацию, которую я предоставил. Это должно помочь вам лучше понять обновления состояния и как их правильно реализовать.