Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 导致钩子对象更新时重新渲染的最佳方法_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 导致钩子对象更新时重新渲染的最佳方法

Javascript 导致钩子对象更新时重新渲染的最佳方法,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,假设我有这样一个功能组件: function App(){ const [obj, setObj] = useState({arr:[1,2,3,4,5]}) const swap = (a,b)=>{ const updatedArr = Object.assign( obj.arr, { [a.toString()]:obj.arr[b], [b.toString()]:obj.arr[a] }

假设我有这样一个功能组件:

function App(){

  const [obj, setObj] = useState({arr:[1,2,3,4,5]})

  const swap = (a,b)=>{
    const updatedArr = Object.assign(
      obj.arr,
      {
        [a.toString()]:obj.arr[b],
        [b.toString()]:obj.arr[a]
      }
    )
    setObj(
      Object.assign(
        obj,
        {arr:updatedArr}
      )
    )
  };

  const buttonAction = (e) => {
    e.preventDefault();
    swap(0,4)
  }

  return <div>
    <button onClick = {buttonAction}>swap</button>
    <ul>
    {
      obj.arr.map(
        item=>{return <li key={item.toString()}>{item}</li>}
        )
    }
    </ul>
  </div>
}
因此,通过将更新的对象分配给新对象,我可以强制重新渲染。这是最好的方法吗?或者,当钩子中的对象发生变化时,有没有更好的方法让组件重新渲染


更新:在有人问我“更好”是什么意思之前,我指的是更“反应式”的东西,这与设计框架的人的意图一致,他们肯定已经预料到了这样的情况

看起来您正在直接修改状态,这导致更新不会触发渲染

setObj(
    Object.assign(
        obj,
        {arr:updatedArr}
    )
)
Object.assign
直接使用新的有序arr更改obj变量(您的状态)。然后
setObj
将此obj分配给自身-此时react将比较对象(与
Object.is
)以确定是否需要渲染。由于它是完全相同的对象,因此不会重新渲染

在工作更新中,您正在指定一个新对象,因此react将进行渲染

也就是说,react-y的方法是不直接修改状态(基本上就是你所做的轻微修改)


看起来您正在直接修改状态,这导致更新不会触发渲染

setObj(
    Object.assign(
        obj,
        {arr:updatedArr}
    )
)
Object.assign
直接使用新的有序arr更改obj变量(您的状态)。然后
setObj
将此obj分配给自身-此时react将比较对象(与
Object.is
)以确定是否需要渲染。由于它是完全相同的对象,因此不会重新渲染

在工作更新中,您正在指定一个新对象,因此react将进行渲染

也就是说,react-y的方法是不直接修改状态(基本上就是你所做的轻微修改)


如果你将项目索引用作
  • 的键而不是项目值,会发生什么情况?@Remeus我尝试过,但没有改变任何事情。如果你将项目索引用作
  • 的键而不是项目值,会发生什么情况?@Remeus我尝试过,但没有改变任何事情。是的,我认为你的诊断是正确的;我就是这么想的。如果是这样的话,那么唯一的解决方法就是把它复制到一个新的对象上。我会等一两天,如果没有其他人有更好的想法,我会把它作为解决办法;我就是这么想的。如果是这样的话,那么唯一的解决方法就是把它复制到一个新的对象上。我会等一两天,如果没有其他人有更好的想法,我会把它作为解决方案。
    const swap = (a,b)=>{
        const updatedArr = Object.assign(
            [...obj.arr],
            {
                [a.toString()]:obj.arr[b],
                [b.toString()]:obj.arr[a]
            }
        )
        setObj(
            Object.assign(
                {},
                obj,
                {arr:updatedArr}
            )
        )
    };