функция обновления, возвращаемая ловушкой useState, не обновляющая значение - PullRequest
1 голос
/ 28 июня 2019

Нечто очень странное происходит. У меня есть значение состояния, которое определяется следующим образом:

const [heightField, setHeightField] = useState<FormField<string>>(new FormField<string>(""));

Я также определил хук useEffect, связанный с этим значением состояния, он определяется следующим образом:

useEffect(() => console.log('heightfield changed, hi from the useEffect hook!'), [heightField]);

На это значение heightField ссылаются в текстовом поле следующим образом:

      <TextField
    required
    label="Height (cms)"
    margin="normal"
    variant="outlined"
    type="number"
    value={heightField.value}
    onChange={(event) => {
      setHeightField(new FormField<string>(event.target.value))
    }}
    error={heightField.error}
    helperText={heightField.errorMessage}
  />

Теперь, когда я вводю текст в текстовое поле, значение heightField соответствующим образом обновляется, и также запускается ловушка useEffect.

Однако при обновлении значения heightField из другой функции его значение не обновляется, а также не запускается ловушка useEffect. Честно говоря, я не понимаю, почему такое поведение происходит. Функция следующая:

const validateHeight = (heightField: FormField<string>) => {

    const heightNumber = parseInt(heightField.value);
    let error = false;
    let errorMessage = "";
    if (!heightNumber) {
      error = true;
      errorMessage = "Wrong number, please verify.";
    }
    else if (heightNumber < 0 || heightNumber > 220) {
      error = true;
      errorMessage = "Please verify the height";
    }
    const nHeightField = new FormField<string>(heightField.value, error, errorMessage);
    setHeightField(nHeightField);
  }

Эта функция вызывается при нажатии кнопки отправки формы и при ее вызове ловушка useEffect не запускается и значение высоты heightField также не обновляется соответствующим образом

Есть что-то, чего мне не хватает? почему это значение не обновляется при вызове функции обновления с новым объектом?

1 Ответ

1 голос
/ 29 июня 2019

Из того, что вы сказали нам в своем вопросе и комментариях, похоже, что ссылка на объект state остается прежней, даже если его свойства изменились. Попробуйте создать копию этого объекта, выполнив что-то вроде следующего:

setState({...heightField});

Или, если вам нужно что-то из предыдущего state перед обновлением:

setState((prevState) => {
 const aux = {...prevState};
 aux.someProp = someOtherValue;
 return aux;
});

Если ваше состояние является объектом, а ссылка на объект остается неизменной между визуализациями, React решит, что он не изменился, и не обновит его. Потому что это только сравнивает значение. Если это number или string, он будет сравниваться по значению, но если это object, он будет сравниваться по ссылке и не будет погружаться в свойства object.

...