Jos*_*ose 5 javascript dictionary reactjs
这更多是一个通用的最佳实践问题。
我一直在使用JavaScript Maps到处乱逛,并一直在尝试查找有关是否将其状态属性设置为Map的反模式/代码气味的更多信息。以下链接是Redux存储库中的问题线程,带有一些注释,例如:
“您可以将Maps和Sets用作状态值,但是由于可序列化性问题,不建议使用它。”
但是,该线程与Redux有关。香草反应怎么样?任何人都有强烈的意见或见识?抱歉,这个问题在错误的地方。
Dom*_*nic 10
如果您不想使用不可变的库,您可以在更改时创建一个新的 Map:
const [someMap, setSomeMap] = useState(new Map());
Run Code Online (Sandbox Code Playgroud)
当您需要更新它时:
setSomeMap(new Map(someMap.set('someKey', 'a new value'));
Run Code Online (Sandbox Code Playgroud)
同样的概念适用于 Redux:
case 'SomeAction':
return {
...state,
yourMap: new Map(state.yourMap.set('someKey', 'a new value'))
}
Run Code Online (Sandbox Code Playgroud)
关于可串行化,它不是本地状态的问题。不过,拥有一个可序列化的 Redux 存储是一种很好的做法。
我可以在我的商店状态中放置函数、承诺或其他不可序列化的项目吗?
强烈建议您只将普通的可序列化对象、数组和原语放入您的存储中。从技术上讲,可以将不可序列化的项目插入存储中,但这样做会破坏存储内容的持久化和再水化能力,并干扰时间旅行调试。
如果您对持久性和时间旅行调试等可能无法按预期工作的事情感到满意,那么完全欢迎您将不可序列化的项目放入您的 Redux 存储中。归根结底,这是您的应用程序,您如何实现它取决于您。与 Redux 的许多其他事情一样,请确保您了解所涉及的权衡。
不幸的是,您可以看到 JSON.stringify 不适用于地图:
const [someMap, setSomeMap] = useState(new Map());
Run Code Online (Sandbox Code Playgroud)
如果您可以在序列化过程之间进行,则可以使用Array.from:
setSomeMap(new Map(someMap.set('someKey', 'a new value'));
Run Code Online (Sandbox Code Playgroud)
React状态应该是不可变的,因为React使用浅比较来检查是否相等。比较标量值(数字,字符串)时,将比较它们的值。比较对象时,它不比较它们的属性-仅比较它们的引用(例如,“它们是否指向同一对象?”)。
ES6 Maps并非一成不变,并且针对可变性进行了优化,这就是为什么不建议在React中按原样使用它们的原因。React不会知道map是否被更新。
var map1 = new Map();
var map2 = map1.set('b', 2); // mutate map
map1 === map2; // true because reference remain unchanged after mutation
Run Code Online (Sandbox Code Playgroud)
您可以根据需要使用Maps,但需要使用一些不变性帮助程序,例如Immutable.js。以下示例使用不可变地图
const { Map } = require('immutable');
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set('b', 2); // Set to same value
map1 === map2; // true
const map3 = map1.set('b', 4); // Set to different value
map1 === map3; // false
Run Code Online (Sandbox Code Playgroud)
参考文献:
https://github.com/reduxjs/redux/issues/1499#issuecomment-194002599 /sf/answers/2525942401/
| 归档时间: |
|
| 查看次数: |
1498 次 |
| 最近记录: |