在更新列表状态后(通过钩子)反应DID NOT更新组件

时间:2020-06-10 07:05:18

标签: javascript reactjs components react-hooks

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


例如下面的代码

如果我按第一个按钮,则第一个h1组件的内容将为24。即使我按第一个按钮,第一个h1组件的组件请勿也会更新。

如果在按下第一个按钮后又按下第二个按钮,则组件 DO 将更新。

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挂钩。但这不是解决方案。 如何更新组件?

2 个答案:

答案 0 :(得分:0)

当状态或道具更改时,请重新渲染组件。并且仅查看状态的内存地址即可确定状态已更改。

在第一个按钮的回调中,通过声明变量temp,您仅在创建tempList数组的浅表副本。因此,即使在修改了第一个对象之后,数组的ID也不会更改,并且react不知道状态已更改。

而且,通过在setState函数中添加回调,您始终可以拥有对当前状态的全新引用:

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>

您在第二个回调中遇到语法错误。除了此修复程序之外,我再次建议将回调函数添加到setTempList函数中。

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

答案 1 :(得分:0)

您似乎正在更新对象的相同引用,而不是推送新对象。试试这个-

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>
)