React DOM не перерисовывает в соответствии с setState - PullRequest
2 голосов
/ 04 августа 2020

Я работаю над частью приложения React, где можно создать задачу, со следующим кодом JSX:

<form>
    <div>
        <label htmlFor="subject">Subject: </label>
        <input type="text" value={todo.subject} onChange={e => handleInput(e, 'subject')} name="subject" id="subject"></input>
    </div>
    <div>
        <label htmlFor="duedate">Due date: </label>
        <input type="date" value={todo.duedate} onChange={e => handleInput(e, 'duedate')} name="duedate" id="duedate"></input>
    </div>
    <div>
        <label htmlFor="description">Description: </label>
        <textarea value={todo.description} onChange={e => handleInput(e, 'description')} name="description" id="description"></textarea>
    </div>
    <div>
        <label htmlFor="sidenote">Sidenotes: </label>
        <textarea value={todo.sidenote} onChange={e => handleInput(e, 'sidenote')} name="sidenote" id="sidenote"></textarea>
    </div>
    <button type="submit" onClick={e => handleSubmit(e)}>Submit</button>
</form>

Состояние todo и handleInput определяются следующим образом:

const [todo, setTodo] = useState({
    'subject': '',
    'duedate': '',
    'description': '',
    'sidenote': ''
});

const handleInput = (e, field) => {
    e.persist();
    setTodo(prevTodo => {
        prevTodo[field] = e.target.value;
        return prevTodo;
    });
}

Запустив console.log(todo) после изменения ввода, я могу подтвердить, что состояние обновляется правильно; однако эти изменения состояния не отображаются как value для входных элементов. И наоборот, изменение handleInput на следующее решило проблему:

const handleInput = (e, field) => {
    e.persist();
    setTodo(prevTodo => {
        let newTodo = {...prevTodo};
        newTodo[field] = e.target.value;
        return newTodo;
    });
}

Учитывая, что обе функции правильно обновили состояние todo, что заставило работать последнюю функцию, а не первую?

1 Ответ

1 голос
/ 04 августа 2020

Как правило, в вашем случае вам нужно вернуть неглубокий объект-копию, а не просто изменить ключ текущего ссылочного состояния, поскольку React не будет сравнивать глубоко в ключе, он просто сравнивает ===, чтобы проверить текущее состояние и следующее состояние отличается, после чего вы решите повторно рендерить или нет, вы также можете переписать, чтобы также работать:

const handleInput = (e, field) => {
   e.persist();
   setTodo(prevTodo => {
      return {
        ...prevTodo,
        [field]: e.target.value,
      }
   });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...