Состояние реакции, приводящее к странному результату при первом изменении состояния

#javascript #reactjs

#язык JavaScript #реагирует на

Вопрос:

Я пытаюсь создать базовый калькулятор квадратных футов, используя состояние реакции, и сталкиваюсь с чем-то, чего раньше не видел. Я уверен, что это то, к чему я еще не привык, но хотел бы знать, ожидается ли это или нет.

Моя цель здесь состоит в том, чтобы, когда пользователь вводит цену, я хотел бы рассчитать ее в режиме реального времени. До сих пор ему это удавалось. ОДНАКО, когда я впервые загружаю страницу и ввожу набор цифр, например, 5 в ширину и 5 в длину, я получаю NaN, напечатанный на консоли. Только после того, как я введу второе число, например 55 и 55, он выполнит расчет и выведет его на консоль.

Я подозревал, что это как-то связано с начальным состоянием, поэтому вместо useState() этого я переключил его на useState(0) . Вместо того, чтобы производить NaN 0 , я печатаюсь на консоли после каждого введенного номера. Опять же, если я введу 55 и 55, это приведет к вычислению. Почему это происходит и как я могу этого избежать?

 const PPSQ = 12;  const [width, setWidth] = useState() const [length, setLength] = useState()  function calculate() {  console.log((width * length) * PPSQ); }  function getWidth(val) {  setWidth(val.target.value)  calculate() }  function getLength(val) {  setLength(val.target.value)  calculate() }  lt;input className="form-control" id="length" name="length" placeholder="Length" type="number" onChange={getLength} autoComplete="off" required /gt;  lt;input className="form-control" id="width" name="width" placeholder="Width" type="number" onChange={getWidth} autoComplete="off" required /gt;  

Ответ №1:

Когда вы вызываете функцию calculate() сразу после setWidth() или setHeight (), вы получаете предыдущие значения состояния компонента (попробуйте записать значения в calculate (), чтобы увидеть их). Правильно будет подождать, пока состояние не изменится с помощью крючка useEffect().

 function ComponentX() {  const PPSQ = 12;   const [width, setWidth] = useState(0);  const [length, setLength] = useState(0);    useEffect( () =gt; {  console.log((width * length) * PPSQ);  });   function getWidth(val) {  setWidth(val.target.value);  }    function getLength(val) {  setLength(val.target.value)  }    return (  lt;gt;  lt;input  className="form-control"  id="length"  name="length"  placeholder="Length"  type="number"  onChange={getLength}  autoComplete="off"  required  /gt;    lt;input  className="form-control"  id="width"  name="width"  placeholder="Width"  type="number"  onChange={getWidth}  autoComplete="off"  required  /gt;  lt;/gt;); }  

Ответ №2:

Когда вы вводите первое значение (например, 18 в длину), другое значение не задается (например, ширина).

Таким образом, при calculate() выводе [the length] x [the width] он равен (в нашем примере) 18 x 0 , который равен 0 .

(Или это может быть равно 18 x NaN , в зависимости от начального значения).


Чтобы исправить это, вы могли вычислять значения только в том случае, если значения не равны нулю или не NaN:

 const PPSQ = 12;  const [width, setWidth] = useState(NaN); // Use NaN const [length, setLength] = useState(NaN); // Use NaN  function calculate() {  if (!Number.isNaN(width) amp;amp; !Number.isNaN(length)) {  console.log((width * length) * PPSQ);  } }  function getWidth(val) {  setWidth(val.target.value)  calculate() }  function getLength(val) {  setLength(val.target.value)  calculate() }  lt;input className="form-control" id="length" name="length" placeholder="Length" type="number" onChange={getLength} autoComplete="off" required /gt;  lt;input className="form-control" id="width" name="width" placeholder="Width" type="number" onChange={getWidth} autoComplete="off" required /gt;