【问题标题】:setState hook changing another statesetState 钩子改变另一个状态
【发布时间】:2021-01-21 16:07:56
【问题描述】:

我是 React 新手。我有下一个问题...

在我的功能组件中,我有许多状态,有 2 个具有相同的字段(一个用于辅助操作)

const [fieldsToEdit, setFieldsToEdit] = useState({}); // This one get populated after the first render
const [auxFields, setAuxFields] = useState({.....})

现在,我有一个调用函数的按钮,该函数只是编辑“fieldsToEdit”,但它也在编辑 auxFields!我在 setState 调用之后和之前实现了编写 console.logs。

const updateEditHandler = (event) => {
  event.persist());


     setFieldsToEdit((prevState) => {
           const { name, value } = event.target;
           if(name === "fecha_presentacion")
              prevState[name] = value;
           else
              prevState[name] = Number(value);
           return ({
              ...prevState
         });
}

我做错了吗?希望你能帮助我。

【问题讨论】:

  • 要记住的一件事是不要改变state。之后,您需要放置整个代码,以便我们可以看到那里发生了什么

标签: javascript reactjs react-hooks


【解决方案1】:

你不应该改变状态。而是在不修改前一个对象的情况下创建一个新对象。

prevState[name] = value; 
return { ...prevState };

上面首先改变了前一个状态,然后返回它的一个副本。而是返回一个包含新值的副本,而不修改之前的状态。

return { ...prevState, [name]: value };

上面复制了之前的状态,并使用value 添加或覆盖(评估的)name 属性。这一切都是在不改变 prevState 的情况下完成的。

将此应用到您的实际代码中,您将得到以下结果。

setFieldsToEdit((prevState) => {
  const { name, value } = event.target;
  
  if (name == "fecha_presentacion") {
    return { ...prevState, [name]: Number(value) };
  } else {
    return { ...prevState, [name]: value };
  }
});

// or (depending on preference)
setFieldsToEdit((prevState) => {
  let { name, value } = event.target;
  if (name == "fecha_presentacion") value = Number(value);
  return { ...prevState, [name]: value };
});

【讨论】:

  • 我以前从未见过useState 钩子的set 函数将另一个函数作为参数。我会假设这会将fieldsToEdit 设置为函数,而不是执行它并保存返回值?
  • @DBS 如果新状态是使用前一个状态计算的,您应该传递一个回调。请参阅 useState - Functional updatessetState 文档。
  • 啊酷,我浏览了文档,显然完全错过了相关部分。很高兴知道这是一个选择。谢谢。
  • 为什么我不应该改变状态? (对不起,无知)。过几天我会尝试这个解决方案,因为我要开始我的假期了,我会在我复出时通知你:)
  • @NicolasVillacorta 没有括号,变量不会被计算,它变成文字name,而不是变量name的内容。见:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
【解决方案2】:
     setFieldsToEdit((prevState) => {
       const { name, value } = event.target;
       if(name === "fecha_presentacion")
          prevState[name] = value;
       else
          prevState[name] = Number(value);
       return ({
          ...prevState
     });

在 prevState[name] = 你改变了状态。如果您不熟悉 lodash,您需要克隆它并使用 lodash deepClone 或 JSON.stringify 然后 JSON.parse 设置它。 您没有共享您的代码,因此 useState({.....}) 没有任何意义。 但是从我从你的代码中得到的总体情况来看,我认为 fieldsToEdit 和 auxFields 具有相同的引用,所以因为你 prevState[name] = 你正在改变两者 尽量不要在任何框架中改变你的状态

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 2019-08-06
    • 1970-01-01
    • 2021-06-02
    相关资源
    最近更新 更多