<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # State 范式化 事實上,大部分程序處理的數據都是嵌套或互相關聯的。例如,一個博客中有多篇文章,每篇文章有多條評論,所有的文章和評論又都是由用戶產生的。這種類型應用的數據看上去可能是這樣的: ```javascript const blogPosts = [ { id: 'post1', author: { username: 'user1', name: 'User 1' }, body: '......', comments: [ { id: 'comment1', author: { username: 'user2', name: 'User 2' }, comment: '.....' }, { id: 'comment2', author: { username: 'user3', name: 'User 3' }, comment: '.....' } ] }, { id: 'post2', author: { username: 'user2', name: 'User 2' }, body: '......', comments: [ { id: 'comment3', author: { username: 'user3', name: 'User 3' }, comment: '.....' }, { id: 'comment4', author: { username: 'user1', name: 'User 1' }, comment: '.....' }, { id: 'comment5', author: { username: 'user3', name: 'User 3' }, comment: '.....' } ] } // and repeat many times ] ``` 上面的數據結構比較復雜,并且有部分數據是重復的。這里還存在一些讓人關心的問題: - 當數據在多處冗余后,需要更新時,很難保證所有的數據都進行更新。 - 嵌套的數據意味著 reducer 邏輯嵌套更多、復雜度更高。尤其是在打算更新深層嵌套數據時。 - 不可變的數據在更新時需要狀態樹的祖先數據進行復制和更新,并且新的對象引用會導致與之 connect 的所有 UI 組件都重復 render。盡管要顯示的數據沒有發生任何改變,對深層嵌套的數據對象進行更新也會強制完全無關的 UI 組件重復 render 正因為如此,在 Redux Store 中管理關系數據或嵌套數據的推薦做法是將這一部分視為數據庫,并且將數據按范式化存儲。 ## 設計范式化的 State 范式化的數據包含下面幾個概念: - 任何類型的數據在 state 中都有自己的 “表”。 - 任何 “數據表” 應將各個項目存儲在對象中,其中每個項目的 ID 作為 key,項目本身作為 value。 - 任何對單個項目的引用都應該根據存儲項目的 ID 來完成。 - ID 數組應該用于排序。 上面博客示例中的 state 結構范式化之后可能如下: ```javascript { posts : { byId : { "post1" : { id : "post1", author : "user1", body : "......", comments : ["comment1", "comment2"] }, "post2" : { id : "post2", author : "user2", body : "......", comments : ["comment3", "comment4", "comment5"] } } allIds : ["post1", "post2"] }, comments : { byId : { "comment1" : { id : "comment1", author : "user2", comment : ".....", }, "comment2" : { id : "comment2", author : "user3", comment : ".....", }, "comment3" : { id : "comment3", author : "user3", comment : ".....", }, "comment4" : { id : "comment4", author : "user1", comment : ".....", }, "comment5" : { id : "comment5", author : "user3", comment : ".....", }, }, allIds : ["comment1", "comment2", "comment3", "commment4", "comment5"] }, users : { byId : { "user1" : { username : "user1", name : "User 1", } "user2" : { username : "user2", name : "User 2", } "user3" : { username : "user3", name : "User 3", } }, allIds : ["user1", "user2", "user3"] } } ``` 這種 state 在結構上更加扁平。與原始的嵌套形式相比,有下面幾個地方的改進: - 每個數據項只在一個地方定義,如果數據項需要更新的話不用在多處改變 - reducer 邏輯不用處理深層次的嵌套,因此看上去可能會更加簡單 - 檢索或者更新給定數據項的邏輯變得簡單與一致。給定一個數據項的 type 和 ID,不必挖掘其他對象而是通過幾個簡單的步驟就能查找到它。 - 每個數據類型都是唯一的,像改評論這樣的更新僅僅需要狀態樹中 “comment > byId > comment” 這部分的復制。這也就意味著在 UI 中只有數據發生變化的一部分才會發生更新。與之前的不同的是,之前嵌套形式的結構需要更新整個 comment 對象,post 對象的父級,以及整個 post 對象的數組。這樣就會讓所有的 Post 組件和 Comment 組件都再次渲染。 需要注意的是,范式化的 state 意味更多的組件被 connect,每個組件負責查找自己的數據,這和小部分的組件被 connect,然后查找大部分的數據再進行向下傳遞數據是恰恰相反的。事實證明,connect 父組件只需要將數據項的 Id 傳遞給 connect 的子對象是在 Redux 應用中優化 UI 性能的良好模式,因此保持范式化的 state 在提高性能方面起著關鍵作用。 ## 組織 State 中的范式化數據 一個典型的應用中通常會有相關聯的數據和無關聯數據的混合體。雖然我們對這種不同類型的數據應該如何組織沒有一個單一的規則,但常見的模式是將關系 “表” 放在一個共同的父 key 中,比如:“entities”。通過這種模式組織的 state 看上去長得像這樣: ```javascript { simpleDomainData1: {....}, simpleDomainData2: {....} entities : { entityType1 : {....}, entityType2 : {....} } ui : { uiSection1 : {....}, uiSection2 : {....} } } ``` 這樣可以通過多種方式進行擴展。比如一個對 entities 要進行大量編輯的應用可能希望在 state 中保持兩組 “表”,一個用于存儲 “當前”(current) 的項目,一個用于存儲 “正在進行中”(work-in-progress) 的項目。當數據項在被編輯的時候,其值可以被復制到 “正在進行中” 的那個表中,任何更新他的動作都將在 “正在進行中” 的表中工作,編輯表單被該組數據控制著,UI 仍然被原始數據控制著。表單的 “重置” 通過移除 “正在進行中” 表的數據項然后從 “當前” 表中復制原始數據到 “正在進行中” 表中就能輕易做到,表單的 “應用” 通過把 “正在進行中” 表的數據復制到 “當前” 表中就能實現。 ## 表間關系 因為我們將 Redux Store 視為數據庫,所以在很多數據庫的設計規則在這里也是適用的。例如,對于多對多的關系,可以設計一張中間表存儲相關聯項目的 ID(經常被稱作 “連接表” 或者 “關聯表”)。為了一致起見,我們還會使用相同的 `byId` 和 `allIds` 用于實際的數據項表中。 ```javascript { entities: { authors : { byId : {}, allIds : [] }, books : { byId : {}, allIds : [] }, authorBook : { byId : { 1 : { id : 1, authorId : 5, bookId : 22 }, 2 : { id : 2, authorId : 5, bookId : 15, } 3 : { id : 3, authorId : 42, bookId : 12 } }, allIds : [1, 2, 3] } } } ``` 像 “查找這個作者所有的書” 這個操作可以通過在連接表上一個單一的循環來實現。相對于應用中一般情況下數據量和 JavaScript 引擎的運行速度,在大多數情況下,這樣操作的性能是足夠好的。 ## 嵌套數據范式化 因為 API 經常以嵌套的形式發送返回數據,所以該數據需要在引入狀態樹之前轉化為規范化形態。[Normalizr](https://github.com/paularmstrong/normalizr) 庫可以幫助你實現這個。你可以定義 schema 的類型和關系,將 schema 和響應數據提供給 Normalizr,他會輸出響應數據的范式化變換。輸出可以放在 action 中,用于 store 的更新。有關其用法的更多詳細信息,請參閱 Normalizr 文檔。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看