Как изменить специальный компонент внутри тега li (reactjs);

#javascript #reactjs #frontend #mern

#javascript #reactjs #интерфейс #mern

Вопрос:

Я написал функциональный компонент react, в котором есть неупорядоченный список. У каждого li есть определенный ключ для него. Внутри li есть тег div и кнопка в нем. Мне нужно изменить состояние конкретной кнопки при нажатии.

     <div>
        <ul>
            {data.map((value,index) => {
                return <li key={value.id}>
                    <div>
                        {value.name}
                    </div>
                    <button
                    onClick={changethislistate}
                    >
                        click
                    </button>
                </li>
            })}
        </ul>
    </div>
 

При нажатии кнопки click мне нужно изменить значение с click на clicked только для этого li. А также мне нужно сделать это в функциональном компоненте.

Ответ №1:

Создайте компонент для li элементов, таким образом, каждый элемент может управлять своим собственным состоянием:

 const ListItem = ({value}) => {
  const [clicked, setClicked] = useState(false);
  return (
    <li>
      <div>{value.name}</div>
      <button onClick={()=> setClicked(prev => !prev)}>{clicked ? "clicked" : "click"}</button>
    </li>
  );
};
 

затем:

 <div>
   <ul>
     {data.map((value,index) => {
        return <ListItem key={value.id} value={value} />        
     })}
   </ul>
</div>
 

Ответ №2:

Добавьте a state к компоненту, то есть объекту, и используйте индекс в качестве ключей:

 const App = (props) => {
  const [state, setState] = React.useState({ 0: false, 1: true });

  const changethislistate = (id) => {
    setState((prev) => ({ ...prev, [id]: !prev[id] }));
  };

  const data = [{ name: "First" }, { name: "Second" }];
  return (
    <div>
      <ul>
        {data.map((value, index) => {
          return (
            <li key={value.id}>
              <div>{value.name}</div>
              <button onClick={() => changethislistate(index)}>
                {state[index] ? "clicked" : "click"}
              </button>
            </li>
          );
        })}
      </ul>
    </div>
  );
};
 

Вот рабочий codepen, чтобы поиграть с ним.

Ответ №3:

При дополнительном ответе вы можете изменить это, не используя state . Вы можете использовать ссылки.

 import React, { useRef } from 'react';

const App = () => {
  const data = [{id:1,name:"test1"},{id:2,name:"test2"}];
  const ref =useRef([]);
  const changethislistate=(id)=>{
    ref.current[id].innerText="clicked"
  }
  
  return (<div>
  <ul>
      {data.map((value,index) => <li key={value.id}>
              <div >
                  {value.name}
              </div>
              <button 
              ref={(element) => ref.current[index] = element}
              onClick={()=>changethislistate(index)}
              >
                  click
              </button>
          </li>
      )}
  </ul>
</div>)
}
export default App;