javascript - 导致钩子(Hook)对象更新重新渲染的最佳方法

标签 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]
      }
    )
    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>
}

“交换”按钮使 swap 函数交换数组的第一个和最后一个元素。当我在开发人员工具中检查这一点时,实际上发生的情况是:

函数之前: object before function

后功能: object after function

但是,它不会导致重新渲染,因此列表在 View 中保持不变。

我可以通过更改交换函数以包含以下内容来强制重新渲染:

const newObj = Object.assign(
    obj,
    {arr:updatedArr}
  )
setObj(
  Object.assign(
    {},
    newObj
  )
)

因此,通过将更新后的对象分配给新对象,我可以强制重新渲染。这是最好的方法吗?或者是否有更好的方法让组件在钩子(Hook)中的对象发生变化时重新渲染?

更新:在有人问我“更好”是什么意思之前,我的意思是更“React-y”的东西,这符合设计框架的人的意图,他们肯定已经预料到了一种情况像这样。

最佳答案

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

setObj(
    Object.assign(
        obj,
        {arr:updatedArr}
    )
)

Object.assign 正在使用新的有序 arr 直接更改 obj 变量(您的状态)。然后 setObj 获取这个 obj 并将其分配给自己 - 此时,react 正在比较对象(与 Object.is)来决定是否需要渲染。由于它是完全相同的对象,因此不会重新渲染。

在您的工作更新中,您将分配给一个新对象,因此 react 将呈现。

也就是说,react-y 的方法是不直接修改状态(本质上是你正在做的稍微修改的事情)

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

关于javascript - 导致钩子(Hook)对象更新重新渲染的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57297882/

相关文章:

ios - 从iOS主屏幕启动的React Web App怪异行为

reactjs - 如何在 React hooks 中使用静态变量

javascript - 使用 React Hooks 更改元素类名称和 sibling

javascript - Couchdb Map函数获取两个日期之间的数据

javascript - 从 react js中的对象数组中删除一个元素

javascript - DOM 渲染后在 React 中执行 Vanilla JS 脚本

javascript - 如何动态地将类添加到焦点输入字段的父 div?

javascript - 当 React 中 ref.current 发生变化时收到通知

javascript - JS、Canvas - ctx.drawImage() 不起作用

javascript - Skype JavaScript 插件格式