首页 > 解决方案 > Redux 存储区中仅在 Redux 外部发生突变的可变对象会导致意外的副作用吗?

问题描述

鉴于这种情况:

我的问题是,这样做是否“安全”,或者可能存在有问题的副作用,如果是这样,为什么?特别是,这是否会影响性能,是否会扰乱 Redux 重新计算状态的方式,如果对象作为道具从 Redux 存储传递给 React 组件,是否会扰乱 React 组件的渲染?

标签: javascriptreactjsreduxreact-reduximmutability

解决方案


永远不应该改变处于 Redux 状态的值,永远

这可能而且绝对会导致副作用,包括应用程序可能不会在需要时呈现。

如果您所指的这个“可变对象”是某种类实例或类似的,那么它也不属于 Redux 存储:

编辑

根据评论中的讨论,我建议如何处理类似 WebGL 上下文的事情:

const SomeParentComponent = () => {
  // Use Redux state to decide when we should show this
  const showWebGl = useSelector(state => state.ui.showWebGl);
  // Standard hooks "forceRender" implementation
  const [, forceRender] = useReducer(c => c + 1, 0)
  // Ref to hold the WebGL instance
  const webGlRef = useRef(null);

  useLayoutEffect(() => {
    if (showWebGl) {
      webGlRef.current = magicallyCreateWebGlInstance();
      forceRender(); // have to force a re-render to pass down the ref value
    }
    
    return () => {
      if (webGlRef.current) {
        magicallyDestroyWebGlInstance(webGlRef.current)
      }
    }

  }, [showWebGl])

  return (
    <MyWebGlContext.Provider value={webGlRef.current>
      <RestOfAppGoesHere />
    </MyWebGlContext.Provider>
  )
}

WebGL 实例本身不属于 store,因为它不是state,也不是可序列化的。不应将 Redux 存储仅用作传递任意值的一种方式,尤其是当这些值不是纯 JS 数据时。

这样,Redux 状态仍然会驱动 WebGL 实例是否正在创建,但实例本身完全存在于 UI 层中,并且仍然可供组件树的其余部分访问。


推荐阅读