Простой setState для объекта с использованием хуков

const [state, setState] = useState({ city: '', country: '' });

const handleCityChange = event => {
  setState(prevState => {
    console.log(prevState);
    return { ...prevState, city: event.target.value };
  });
};

//...

<input
  type="text"
  placeholder="city"
  value={state.city}
  onChange={handleCityChange}
/>

Я пытаюсь разрушить prevState, который является объектом, и обновить только свойство city. При первом нажатии клавиши он работает нормально, без ошибок, но как только я набираю вторую букву, я получаю ошибку

Uncaught TypeError: невозможно прочитать значение свойства null

Могу ли я узнать, из какой части исходит нуль? И с консоли Chrome я вижу предупреждение ниже, не уверен, связано ли оно

Предупреждение: это синтетическое событие используется повторно из соображений производительности. Если вы видите это, вы обращаетесь к свойству target в синтетическом событии выпущенного / аннулированного. Для него установлено значение null. Если вы должны сохранить исходное синтетическое событие, используйте event.persist (). См. Https: ... // response-event-pooling для получения дополнительной информации.

ОБНОВЛЕНИЯ. Если мы не используем setState функционально, значит, все работает нормально?

const handleCityChange = event => {
  setState({ ...state, city: event.target.value });
};

person Isaac    schedule 04.04.2019    source источник


Ответы (1)


В React событие должно обрабатываться синхронно. Вы можете извлечь value из цели перед вызовом setState:

const handleCityChange = event => {
  const { value } = event.target;
  setState(prevState => {
    return { ...prevState, city: value };
  });
};

Другой способ сделать это - persist событие, и оно может быть используется асинхронно.

const handleCityChange = event => {
  event.persist();
  setState(prevState => {
    return { ...prevState, city: event.target.value };
  });
};
person Tholle    schedule 04.04.2019
comment
Я только что узнал, что без использования функционала setState проблема будет устранена? Могу я узнать, чем они отличаются, если вы хотите немного подробнее объяснить, что между ними происходит? - person Isaac; 04.04.2019
comment
Когда вы передаете функцию в качестве аргумента setState, эта функция будет вызываться асинхронно React. Попытка разыменовать event.target.value в этой функции не сработает, поскольку вы не можете использовать событие асинхронно. - person Tholle; 04.04.2019
comment
Вроде как получить картину сейчас. Нужно время, чтобы это переварить. Большое спасибо! - person Isaac; 04.04.2019