javascript - Redux 存储区中仅在 Redux 外部发生突变的可变对象会导致意外的副作用吗?
问题描述
鉴于这种情况:
- Redux 存储中有一个可变对象
- Reducers 不会改变对象;所有 reducer 仍然是没有副作用的纯函数
- 可变对象有时会在 Redux之外发生变异,例如,通过调用对象本身的方法
我的问题是,这样做是否“安全”,或者可能存在有问题的副作用,如果是这样,为什么?特别是,这是否会影响性能,是否会扰乱 Redux 重新计算状态的方式,如果对象作为道具从 Redux 存储传递给 React 组件,是否会扰乱 React 组件的渲染?
解决方案
你永远不应该改变处于 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 层中,并且仍然可供组件树的其余部分访问。
推荐阅读
- javascript - 测试我的全局变量为什么它返回未定义
- html - 将图像从另一个项目的文件夹添加到 HTML?
- python - 如何将if中创建的变量发送到python中的elif?
- sql - 基于特定列中的 DISTINCT 值创建 CASE WHEN 标签
- python - 使用 sys.path.insert 时 python 找不到 fit 文件
- python - 如何仅通过一次迭代找到链表中的四分位数
- ios - AVPlayer 不适用于 iOS 12.2,而它与带有 XCode 12.3 的 iOS 14.3 一起使用
- node.js - 在节点中创建一个 zip 文件并作为 blob 发送
- windows-services - 0x30 的 Windows 服务类型是什么意思?
- python - 使用 serverless-aws-documentation 描述 swagger-ui 的文件上传