Как отследить, какой элемент списка был нажат в React?

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть список опций меню, и мне нужно отслеживать, какой параметр был нажат. Мне также нужно применить другой стиль к выбранному варианту. Вот соответствующий код:

 export default function account() {
  let [currentTab, setCurrentTab] = useState("username")

  const handleListItemClick = (e) => {
    let targetId = e.target.id || e.target.parentNode.id
    if (currentTab !== targetId) setCurrentTab(targetId)
  }

  return (
    <>
      <Layout>
        <div className={styles.contentWrapper}>
          <div className={styles.leftBar}>
            <ul className={styles.listContainer}>
              <li className={`${styles.listItem} ${currentTab === "username" amp;amp; styles.listItemActive} `}
                id="username"
                onClick={handleListItemClick}>
                <FiUser color="#5650bf" size="18px" />
                <span>Update username</span>
              </li>
              <li className={`${styles.listItem} ${currentTab === "topics" amp;amp; styles.listItemActive} `}
                id="topics"
                onClick={handleListItemClick}>
                <FiBookmark color="#5650bf" size="18px" />
                <span>My topics</span>
              </li>
              <li className={`${styles.listItem} ${currentTab === "about" amp;amp; styles.listItemActive} `}
                id="about"
                onClick={handleListItemClick}>
                <FiInfo color="#5650bf" size="18px" />
                <span>Update About page</span>
              </li>
            </ul>
          </div>
        </div>
      </Layout>
    </>
  )
}
  

Код работает, однако я не уверен, правильно ли это делать с помощью React, и есть ли лучший способ решить эту проблему. Спасибо.

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

1. Вы делаете это совершенно правильно … я не уверен, что вам нужно было задавать этот вопрос …?

2. Одна небольшая очистка, вам нужен фрагмент, обертывающий весь оператор return? Он переносит только один элемент JSX, поэтому вы, вероятно, можете его удалить.

3. @DBS это не весь код, а только соответствующий сегмент. Спасибо вам, хотя!

Ответ №1:

Вместо того, чтобы иметь идентификаторы, как насчет простой передачи имени вкладки в обратный вызов click при вызове?

Кроме того, эти разделы будут создавать нежелательную разметку:

 className={`${styles.listItem} ${currentTab === "username" amp;amp; styles.listItemActive}
  

потому что они будут оцениваться className как содержащие false , если условие не выполнено. Используйте условный оператор, чтобы вместо этого они вычисляли пустую строку.

Изменить

 <li className={`${styles.listItem} ${currentTab === "username" amp;amp; styles.listItemActive} `}
  id="username"
  onClick={handleListItemClick}>
  <FiUser color="#5650bf" size="18px" />
  <span>Update username</span>
</li>
  

Для

 <li
  className={`${styles.listItem} ${currentTab === "username" ? styles.listItemActive : ''} `}
  onClick={() => setCurrentTab('username')}
>
  <FiUser color="#5650bf" size="18px" />
  <span>Update username</span>
</li>
  

Нет необходимости handleListItemClick — если новое состояние совпадает со старым состоянием, никаких изменений не произойдет.

Вы также можете абстрагировать имя класса в функцию, которая будет удалена:

 const getClass = thisTab => `${styles.listItem} ${currentTab === thisTab ? styles.listItemActive : ''}`;
  
 className={getClass('username')}
  
 className={getClass('topics')}
  
 className={getClass('about')}
  

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

1. Есть ли снижение производительности onClick={() => setCurrentTab('username')} вместо выполнения onClick={setCurrentTab('username')} и setCurrentTab возврата функции обратного вызова?

2. @TKoL Возможно, что это будет немного медленнее, но это будет абсолютно незначительно, особенно учитывая, что это отдельные уникальные элементы, а не огромный список. Лучше сначала стремиться к лаконичному, читаемому коду.

3. @CertainPerformance понятно в пункте «отдельные уникальные элементы». хороший вызов