繁体   English   中英

更新列表 state 后反应没有更新组件(通过钩子)

[英]React DID NOT update components after update list state (by hook)

当使用 useState 挂钩存储 object 列表时(例如 [{ a:1 }, { a:2 }]),如果我更改列表的元素(对象)的内容,请不要更新组件。


例如在下面的代码中,

如果我按下第一个按钮,第一个 h1 组件的内容将为 24。但是即使我按下第一个按钮,第一个 h1 组件组件也不会更新。

如果我在按下第一个按钮后按下第二个按钮,组件更新。

const [tempList, setTempList] = useState([
  { a: 1 },
  { a: 2 }
])


return (
  <div>
    {
      tempList.map((item, idx) => {
        return <h1>{item.a}</h1>
      })
    }
    <button onClick={() => {
      let temp = tempList;
      temp[0]['a'] = 24
      setTempList(temp)
    }}>modify list</button>
    <button onClick={() => {setTempList(...tempList, {a: 3})}}>insert list</button>
  </div>
)

已经使用了 useReducer 钩子。 但这不是解决方案。 如何更新组件?

当 state 或 props 更改时,React 重新渲染组件。 并且仅通过查看 state 的 memory 地址即可确定 state 发生了变化。

在第一个按钮的回调中,通过声明变量temp ,您只是创建了tempList数组的浅表副本。 因此,即使修改了第一个object,数组的id并没有改变,react也不知道state已经改变了。

此外,通过在setState function 中放置回调,您始终可以对当前的 state 有新的引用:

const [state, setState] = useState(0);
setState(state+1) <-- the state can be stale
setState(state=>state+1) <-- increment is guaranteed

尝试构建另一个数组:

<button onClick={()=>{
  setTempList(tempList=>tempList.map((item,ind)=>{
    if(ind===0){
      return {a:24};
    }
    else{
      return item;
    }
  })
}}>modify list</button>

您在第二个回调中有语法错误。 除了修复之外,我再次建议将回调 function setTempList function。

<button onClick={() => {
  setTempList(tempList=>[...tempList, {a: 3}])
}}>insert list</button>

您似乎正在更新 object 的相同参考,而不是推送新的 object。 尝试这个 -

const [tempList, setTempList] = useState([
  { a: 1 },
  { a: 2 }
])


return (
  <div>
    {
      tempList.map((item, idx) => {
        return <h1>{item.a}</h1>
      })
    }
    <button onClick={() => {
      let temp = [...tempList];
      temp[0] = { a: 24 };
      setTempList(temp)
    }}>modify list</button>
    <button onClick={() => {setTempList(...tempList, {a: 3})}}>insert list</button>
  </div>
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM