Обработчик onClick применяется ко всем элементам после отображения

#reactjs

Вопрос:

У меня есть следующие данные:

 export const Bookings = ({ booking, selectedBookings }) => {
const [selected, setSelected] = React.useState(false)

const handleSelect = (data) => {
    selectedBookings(data)
  }

{booking.map(data => (
        <div
          key={nanoid()}
          className={selected ? styles.selectedDescription : styles.NonSelectedDescription}
           onClick={() => {
             handleSelect(data.name); // when I add this it does not trigger the style toggling
            setSelected(!selected) // if I keep only this handler it works but for all childrens
          }}
        >
          {description}
        </div>
 

В этом коде я хочу отправить данные родительскому компоненту и применить определенные стили при нажатии на бронирование, НО у меня есть 2 проблемы:

1 — когда я удаляю handleSelect(data.name) стили, они применяются ко всем детям, а не к одному ребенку.

2 — когда я добавляю handleSelect(data.name) обработчик, стили вообще не работают, но обработчик отправляет данные родителю

Так есть ли здесь какие-то проблемы?

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

1. У вас есть только ОДНО selected значение, но у вас есть несколько бронирований. Вам необходимо отслеживать выбранный штат для каждого отдельного бронирования. Вы можете сделать это, сохранив массив выбранных логических значений, по одному для каждого бронирования, и изменив их. Или переместите бронирование в его собственный компонент, имеющий собственное внутреннее состояние, которое отслеживает, выбрано оно или нет. Также я не знаю, что nanoid() делает, но если он возвращает новое случайное значение каждый раз, когда он вызывается, то key={nanoid()} это плохая идея, потому что ключи должны быть уникальными и постоянными . Это будет запускать функцию nanoid при каждом рендеринге

Ответ №1:

Вам нужно сохранить разные selected логические значения для всех бронирований;

Попробуйте что-нибудь вроде приведенного ниже:-

  1. Измените selected состояние на объект:-
 const [selected, setSelected] = React.useState({})
 
  1. Изменение handleSelect , как показано ниже:-
 const handleSelect = (dataName) => {
    setSelected({...selected, selected[dataName]: !selected[dataName]});
  }
 
  1. Изменение className , div как показано ниже:-
 {booking.map(data => (
  <div
    key={nanoid()}
    className={selected[data.name] ? styles.selectedDescription : styles.NonSelectedDescription}
    onClick={() => { handleSelect(data.name); }} 
   >
     {description}
   </div>
))}
 

Примечание:- Все имена бронирования должны быть уникальными, если они не уникальны, вам необходимо передать уникальное значение в handleSelect функции.