簡體   English   中英

將 ES6 Map 與 React 和/或 Redux 一起使用

[英]Using ES6 Map with React and/or Redux

我正在考慮使用 ES6 Map對象為我進行散列,而不是創建自定義散列函數。 然而,在我看來,它對不變性的支持並不多,這對於 React 和 Redux 來說都是關鍵。

我習慣於不使用任何庫來實現不變性,而只使用簡單的解構:

const newObj = { ...prevObj, newKey: "value" }

或使用數組映射/過濾。

但是,ES6 Map具有直接更新對象本身的方法。

我能想到的是做這樣的事情:

var myMap = new Map()
Var myNewMap = { ...myMap.set() }
this.setState({ myMap:myNewMap })

但我不確定這是否可行。

JavaScript 中的所有對象本質上都是引用類型( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#comparing_objects )。 Redux 中狀態對象不可變的唯一原因是庫本身不允許您直接修改getState返回的狀態對象。

此外,JavaScript 對象本身就是一個字典,因此通過屬性名稱從該狀態對象中獲取數據仍然是 O(1) 時間復雜度

如果您只想要一個類型安全的鍵值存儲,您可以使用以下語法:

entities: { [id: number]: MyEntity },
...

我最近考慮使用 Map 數據結構和 react +redux 並決定反對它。

盡管在某些用例中使用 Map 有一點性能優勢,但主要是因為編譯器更清楚會發生什么。 你會免費獲得一個尺寸道具 :)

我認為反對這種方法的原因更多:

首先,redux 不喜歡不可序列化的對象 - faq 如果您想使用 SSR 或將數據保存在 localStorage 中,它將不起作用。

您無法享受 redux 工具包中的許多功能,因為它們假定/創建簡單的對象數據結構。 例如createEntityAdapter - 我個人認為很棒

您可以在每個 reducer 中創建一個新地圖,但它可能會很快變得煩人,而且我不確定性能。

React 並不太在意 :)

我在使用 Redux 的 React 項目中使用 ES6。

用例 #1

在一個組件內:

我收到數據,然后我需要處理它,例如為每個元素添加一些標志和/或附加參數,然后我將它作為 ES6 Map 存儲在組件中(而不是組件狀態)。

稍后當我需要更新數據時(例如,獲取了新元素),我使用 Thunk 在 redux 中設置了一個loading標志,稍后又回到false觸發更新。

我用新數據更新我的 ES6 地圖,對其進行變異,但沒有創建新地圖。 我的組件由於loading標志而更新,並使用內部地圖中的新數據重新渲染

用例 #2

在 Redux 狀態

我的 Redux 狀態中有一個 ES6 Map,因為我想與多個組件共享它。 我在減速器中保持不變:

 const newMap = new Map(oldMap.entries())

但是在每次更新時創建新地圖只有在您不經常更新它但經常從中讀取時才有用。

在我的情況下,我必須在 Redux 狀態下使用 Map,因為 ES6 Map 保持元素的順序,同時提供對它們的 O(1) 訪問。

因此,我建議您找出使用 ES6 Map 有益的部分,以及與常規Object一起使用的部分。

在 state 內使用 ES6 的Map其實非常簡單。 你需要使用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!'}),
};

要更新狀態,您可以使用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});
}

那么,這里發生了什么? 我們可以隨時用表格網格上的任何位置更新狀態。 例如,如果我們已經有 500 個帶有文本的網格,我可以再添加一個網格文本字段,使用this.updateState(Map({'1000,500':'my text at position 1000x500!'})); . 通過這種方式, Map()可以在狀態中使用,並且它保留了 O(1) 查找單個更改的好處,因為我們的updateState()處理它。

這也繞過了render()的大部分使用,但這是一個設計決定。 我使用了 1,000x1,000 表格網格的示例,因為在使用render()時,擁有 1,000^2 個唯一的、有狀態的元素具有巨大的加載/處理時間,在這種情況下, Map()可以正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM