как правильно отобразить состояние в React?

#javascript #reactjs

Вопрос:

У меня есть компонент react, и я использую useState для создания таких значений

 const [value, setValue] = useState([
    { id: 0, name: "rafi" },
    { id: 1, name: "fii" },
  ]);
 

и я создал функцию внутри компонента react для переименования массива и удаления массива

  function arrayObjectIndexOf(myArray, searchTerm, property) {
    for (var i = 0, len = myArray.length; i < len; i  ) {
      if (myArray[i][property] === searchTerm) return i;
    }
    return -1;
  }


const renameValue = (id, name) => {
    let index = arrayObjectIndexOf(value, id, "id");
    let newValue= value;
    neValue[index]["name"] = name;
    setValue(newValue);
  };

const deleteValue= (id) => {
    let newValue= value.filter((list) => list.id !== id);
    setValue(newValue);
  };

 

и я визуализирую компонент следующим образом

 <>
        <h1>LIST</h1>
        {value.map((list) => {
          return (
            <div key={list.id}>
              <h1>{list.name}</h1>
              <button type="button" onClick={() => deleteValue(list.id)}>
                Remove
              </button>
              <button
                type="button"
                onClick={() => renameValue(list.id, "raa")}
              >
                Rename
              </button>
            </div>
          );
        })}
    </>
 

В компоненте React кнопка переименования не работает (имя в списке не изменилось), но когда я нажимаю кнопку переименования двух кнопок и продолжаю нажимать кнопку удаления, имя в списке меняется.

Есть ли кто-нибудь, кто может помочь мне в этой проблеме? Чтобы кнопка переименования работала правильно. запросите предложения о том, как правильно отображать компоненты в React.

в мире. тх.

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

1. Что такое остаток?

Ответ №1:

Ты изменяешь свое первоначальное состояние. В результате, когда вы возвращаете то же значение для своего состояния, react не будет повторно отображать ваш компонент. Обновление DOM может быть дорогостоящей операцией, поэтому React пытается свести к минимуму количество его обновлений. Если ваше старое состояние равно ( === ) вашему новому состоянию, то react пропустит рендеринг.

 const currState = [{}, {}, {}];
const newState = currState; // this does NOT create a copy, it just points newState to the same array in memory as currState
currState[0] = 0; // change value (mutate original `myState`)
console.log(currState === newState); // true (as exactly the same array in memory) 

Вместо этого сохраняйте свои изменения неизменными (т. Е. Не изменяйте свое value состояние напрямую). Вы можете сделать это, создав новый массив с измененными значениями объектов. Приведенный ниже код отобразится в вашем value массиве, который создаст новый массив значений, если идентификатор текущего объекта совпадает с указанным идентификатором, переданным в вызов функции, то вы можете вернуть измененный объект с именем, перезаписанным как имя, переданное в вашу функцию:

 const renameValue = (id, name) => {
  setValue(oldValue => oldValue.map(
    obj => obj.id === id ? {...obj, name} : obj
  ));
};
 

См. Рабочий пример:

 const {useState} = React;

const App = () => {
  const [value, setValue] = useState([
    { id: 0, name: "rafi" },
    { id: 1, name: "fii" },
  ]);
  
  const renameValue = (id, name) => {
    setValue(oldValue => oldValue.map(
      obj => obj.id === id ? {...obj, name} : obj
    ));
  };

  const deleteValue= (id) => {
    let newValue= value.filter((list) => list.id !== id);
    setValue(newValue);
  };
  
  return <React.Fragment>
    <h1>LIST</h1>
    {value.map((list) => {
      return (
        <div key={list.id}>
          <h1>{list.name}</h1>
          <button type="button" onClick={() => deleteValue(list.id)}>
            Remove
          </button>
          <button
            type="button"
            onClick={() => renameValue(list.id, "raa")}
          >
            Rename
          </button>
        </div>
      );
    })}
    </React.Fragment>
}

ReactDOM.render(<App />, document.body); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>