React在更新列表状态后没有更新组件(通过钩子)

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

当使用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>
)

I 已经 使用了useReducer钩子。如何更新组件?

javascript reactjs components hook
1个回答
0
投票

当状态或道具发生变化时,React会重新渲染组件。而且它只通过查看状态的内存地址来判断状态是否发生了变化。

在第一个按钮的回调中,通过声明变量 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>

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>
)
© www.soinside.com 2019 - 2024. All rights reserved.