Реагировать useState не удалось обновить двустороннюю привязку - PullRequest
1 голос
/ 19 сентября 2019

Я пытаюсь настроить так, чтобы при вводе имени на входе компонента Person состояние в компоненте App обновлялось и, в свою очередь, обновлялось значение свойства Person, однако при изменении состоянияпроисходит, но реквизит не обновляется, может кто-нибудь помочь мне разобраться в чем дело?

Приложение

const App = () => {
  const [persons, setPersons] = useState([
    {id: "key1", name: "Daniel", age: "28"},
    {id: "key2", name: "John", age: "30"},
    {id: "key3", name: "Doe", age: "60"}
  ]);

  const nameChangedHandler = (id, event) => {
    console.log(event.target.value);
    console.log(id);
    const personIndex = persons.findIndex(p => {
      return p.id === id;
    });

    const person = {
      ...persons[personIndex]
    };

    person.name = event.target.value;

    const pers = [...persons];
    persons[personIndex] = person;

    setPersons(pers);
    console.log(persons);
  };

  let people = persons.map((person, index) => {
    return (
      <Person
        name={person.name}
        key={person.id}
        age={person.age}
        changed={nameChangedHandler.bind(this, person.id)}
      />
    );
  });

  return <div className="App">{people}</div>;
};

Персона

const person = props => (
  <div className={style.Person}>
    <p onClick={props.click}>
      I'm {props.name}, and I am {props.age}!
    </p>
    <input type="text" onChange={props.changed} value={props.name} />
  </div>
);

Ответы [ 2 ]

5 голосов
/ 19 сентября 2019

Вы присваиваете неверную переменную, попробуйте следующее:

const pers = [...persons];
pers[personIndex] = person;

И все должно работать как положено.Так как вы обновляли свой объект состояния persons вместо объекта, который вы клонировали pers, который вы использовали для установки состояния, в журнале консоли отображался ожидаемый результат, но вашсостояние не обновлялось должным образом.

Проверьте это работает stackblitz

2 голосов
/ 19 сентября 2019

Если честно, я бы использовал простую функцию map, чтобы изменить имя конкретного человека.

Внутри nameChangedHandler функция:

const updatedPersons = persons
   .map((person) => person.id === id ? {...person, name: event.target.value} : person);

, а затем обновитьлокальное состояние

setPersons(updatedPersons);

Должно работать как положено.

...