setState 仅捕获最后一个给定值

问题描述 投票:0回答:3

为什么状态只在最后一个 if en else 语句中更新。 仅

setFilledIn
中的年龄设置为
true
false

有人可以帮助我理解 React 中的状态吗? 因为我不知道我做错了什么。

顺便说一下,如果我注释掉最后一个 if 语句,那么 lastName 的 if 语句就可以工作。

const [filledIn, setFilledIn] = useState({
firstName: true,
lastName: true,
age: true,
});

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (firstNameRef.current == null || firstNameRef.current.value === "") {
  setFilledIn({ ...filledIn, firstName: false });
} else {
  setFilledIn({ ...filledIn, firstName: true });
  person2.firstName = firstNameRef.current.value;
}
if (lastNameRef.current == null || lastNameRef.current.value == "") {
  setFilledIn({ ...filledIn, lastName: false });
} else {
  setFilledIn({ ...filledIn, lastName: true });
  person2.lastName = lastNameRef.current.value;
}

 if (ageRef.current == null || ageRef.current.value == "") {
   setFilledIn({ ...filledIn, age: false });
 } else {
   setFilledIn({ ...filledIn, age: true });
   person2.age = parseInt(ageRef.current.value);
 }

};
reactjs if-statement react-hooks state setstate
3个回答
1
投票

filledIn
在组件重新渲染之前不会改变,这里对代码状态的每次更新都不会重新渲染组件,只有当所有代码都在
handleSubmit
完成执行时才会发生
。因此,由于我们仍然处于相同的渲染中,即使您更新
firstName
filledIn
,然后尝试以这种方式更新
lastName

setFilledIn({ ...filledIn, lastName: false });

filledIn
仍然保持相同的值,没有任何更新。
但是有一种方法:

setFilledIn((prev) => {
  return {
    ...prev,
    lastName: false,
  };
});

使用

prev
,即使组件尚未重新渲染,您也可以访问状态的最后一个值,然后您返回的是您希望状态更新的值。

这实际上是更新状态的最佳方法,您希望它始终根据其先前的值而不是当前渲染期间的值进行更新,您遇到的情况就是一个很好的例子,说明了这种方法如何更好。


0
投票

我还没有对此进行测试,因此它只能作为有根据的猜测。但我假设它与您每次调用 setState 时使用 spread 实用程序(...)的用户有关。从技术上讲,您不需要这些,因为您已经使用 useState 初始化了状态。但是,如果您想使用它们而不是初始化状态,那么您必须在密钥对中的名称空间周围放置 [] 。例如:

setFilledIn({ ...filledIn, [lastName]: false });

setFilledIn({ lastName: false });

希望这有帮助! 这里对 setState 和 useState 钩子有很好的解释。


0
投票

问题是您要分别更新每个字段的状态,因此只有最后一个字段的更新才会反映在最终状态中。这是因为 setFilledIn 函数调用是异步的,每次调用都会覆盖之前的更新。

要解决此问题,您可以在检查所有字段后在函数结束时更新状态一次。

const [filledIn, setFilledIn] = useState({
  firstName: true,
  lastName: true,
  age: true,
});

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  let updatedFilledIn = { ...filledIn };

  if (firstNameRef.current == null || firstNameRef.current.value === "") {
    updatedFilledIn.firstName = false;
  } else {
    updatedFilledIn.firstName = true;
  }

  if (lastNameRef.current == null || lastNameRef.current.value === "") {
    updatedFilledIn.lastName = false;
  } else {
    updatedFilledIn.lastName = true;
  }

  if (ageRef.current == null || ageRef.current.value === "") {
    updatedFilledIn.age = false;
  } else {
    updatedFilledIn.age = true;
  }

  setFilledIn(updatedFilledIn);
};

或者你可以将其简化为

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault();
  let updatedFilledIn = { ...filledIn };

  const fields = {
    firstName: firstNameRef,
    lastName: lastNameRef,
    age: ageRef,
  };

  Object.entries(fields).forEach(([fieldName, fieldRef]) => {
    if (fieldRef.current == null || fieldRef.current.value === "") {
      updatedFilledIn[fieldName] = false;
    } else {
      updatedFilledIn[fieldName] = true;
    }
  });

  setFilledIn(updatedFilledIn);
};

© www.soinside.com 2019 - 2024. All rights reserved.