在 React 和/或 Redux 中使用 ES6 Map

Vin*_*Rye 9 javascript dictionary reactjs redux react-redux

我正在考虑使用 ES6 Map对象为我做散列,而不是创建自定义散列函数。然而,在我看来,它对不变性的支持并不多,这对于 React 和 Redux 来说都是一个关键的事情。

我习惯于不使用任何库来实现不变性,而只使用简单的解构:

const newObj = { ...prevObj, newKey: "value" }
Run Code Online (Sandbox Code Playgroud)

或使用数组映射/过滤。

但是,ES6Map具有直接更新对象本身的方法。

我能想到的是做这样的事情:

var myMap = new Map()
Var myNewMap = { ...myMap.set() }
this.setState({ myMap:myNewMap })
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否有效。

Jar*_*ach 5

如果您只想要类型安全的键值存储,可以使用以下语法:

entities: { [id: number]: MyEntity },
...
Run Code Online (Sandbox Code Playgroud)


Ali*_*ssa 5

I thought about using Map data structure with react +redux recently and decided against it.

Though there is a slight performance benefit, for some use cases, in using the Map, mostly because the compiler knows better what to expect. And you get a size prop for free :)

I think there are more reasons agains this approach:

First of all redux doesn't like non serializable object - faq. it won't work if you want to use SSR or save your data in localStorage.

You can't enjoy many features in the redux toolkit, because they assume / create simple object data structures. for example the the createEntityAdapter - which I personally think is great

You can create a new map in each reducer, but it might get annoying pretty fast, and I'm not sure about the performance.

React doesn't care that much though :)


Hol*_*ger -4

Map实际上在国内使用 ES6 非常容易。您需要使用ReactDOMReactDOM.render(document.getElementById('someid'), map.get("123"));。但要使其在优化方面具有任何优势,就有点复杂了。它可能只对某些应用程序有用。

为了避免严格抽象,让我们看一个示例应用程序:DOM 是 HTML <table>,ReactJS 状态是Map坐标和值。这些<td>元素将具有坐标 ID,例如id="pos-1,2"第一行、第二列的位置。现在该州可能看起来像......

this.state = {
    'coordinates': Map({'1,2':'my 1/2 text!', '4,5':'my 4/5 text!'}),
};
Run Code Online (Sandbox Code Playgroud)

要更新状态,您可以updateState()...

updateState(newmap) {
    const coordinates = this.state.coordinates;
    newmap.keys().forEach((key) => {
        const parent = document.getElementById('pos' + key);
        const text = newmap.$key;
        ReactDOM.unmountComponentAtNode(parent);
        ReactDOM.render(parent, (<span>{text}</span>);
        coordinates.set(key, text);
    });
    this.state.setState({'coordinates':coordinates});
}
Run Code Online (Sandbox Code Playgroud)

那么,这里发生了什么?我们可以随时在表格网格上的任何位置更新状态。例如,如果我们已经有 500 个带有文本的网格,我可以再添加一个网格文本字段,扩展名为this.updateState(Map({'1000,500':'my text at position 1000x500!'}));. 通过这种方式,Map()可以在状态中使用,并且它保留了对单个更改进行 O(1) 查找的优点,因为我们updateState()可以处理它。

这也绕过了大部分的使用render(),但这是一个设计决策。我使用了 1,000x1,000 表格网格的示例,因为拥有 1,000^2 个唯一的有状态元素在使用 时会产生巨大的负载/处理时间render(),在这种情况下,Map()效果会很好。