<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # `combineReducers` 進階 Redux 引入了非常實用的 `combineReducers` 工具函數,但我們卻有意將它限制于單一的應用場景:把不同片段的 state 的更新工作委托給一個特定的 reducer,以此更新由普通的 JavaScript 對象構成的 state 樹。它不解決 Immutable.js Maps 所構建的 state tree,也不會把其余部分的 state 作為額外參數傳遞給 reducer 或者排列 reducer 的調用順序,它同樣不關心 reducer 如何工作。 于是一個常見問題出現了,“`combineReducers` 如何處理這些應用場景呢?”通常給出的回答只是“你不能這么做,你可能需要通過其他方式解決”。**一旦你突破 `combineReducers` 的這種限制,就是創建各色各樣的“自定義” reducer 的時候了**,不管是為了解決一次性場景的特殊 reducer,還是能夠被廣泛復用的 reducer。本文為幾種典型的應用場景提供了建議,但你也可以自由發揮。 ## 結合 Immutable.js 對象使用 reducers 由于目前 `combineReducers` 只能處理普通的 JavaScript 對象,對于把 Immutable.js Map 對象作為頂層 state 樹的應用程序來說,可能無法使用 `combineReducers` 管理應用狀態。因為很多開發者采用了 Immutable.js,所以涌現了大量提供類似功能的工具,例如 [redux-immutable](https://github.com/gajus/redux-immutable)。這個第三方包實現了一個能夠處理 Immutable Map 數據而非普通的 JavaScript 對象的 `combineReducers`。 ## 不同 reducers 之間共享數據 類似地,如果 `sliceReducerA` 為了處理特殊的 action 正好需要來自 `sliceReducerB` 的部分 state 數據,或者 `sliceReducerB` 正好需要全部的 state 作為參數,單單就 `combineReducers` 是無法解決這種問題的。可以這樣來解決:把所需數據當額外參數的形式傳遞給自定義函數,例如: ```js function combinedReducer(state, action) { switch (action.type) { case 'A_TYPICAL_ACTION': { return { a: sliceReducerA(state.a, action), b: sliceReducerB(state.b, action) } } case 'SOME_SPECIAL_ACTION': { return { // 明確地把 state.b 作為額外參數進行傳遞 a: sliceReducerA(state.a, action, state.b), b: sliceReducerB(state.b, action) } } case 'ANOTHER_SPECIAL_ACTION': { return { a: sliceReducerA(state.a, action), // 明確地把全部的 state 作為額外參數進行傳遞 b: sliceReducerB(state.b, action, state) } } default: return state } } ``` 另一種解決“共享片段數據更新” (shared-slice updates) 問題的簡單方法是,給 action 添加額外數據。可以通過 thunk 函數或者類似的方法輕松實現,如下: ```js function someSpecialActionCreator() { return (dispatch, getState) => { const state = getState() const dataFromB = selectImportantDataFromB(state) dispatch({ type: 'SOME_SPECIAL_ACTION', payload: { dataFromB } }) } } ``` 因為 B 的數據已經存在于 action 中,所以它的父級 reducer 不需要做任何特殊的處理就能把數據暴露給 `sliceReducerA`。 第三種方法是:使用 `combineReducers` 組合 reducer 來處理“簡單”的場景,每個 reducer 依舊只更新自己的數據;同時新加一個 reducer 來處理多塊數據交叉的“復雜”場景;最后寫一個包裹函數依次調用這兩類 reducer 并得到最終結果: ```js const combinedReducer = combineReducers({ a: sliceReducerA, b: sliceReducerB }) function crossSliceReducer(state, action) { switch (action.type) { case 'SOME_SPECIAL_ACTION': { return { // 明確地把 state.b 作為額外參數進行傳遞 a: handleSpecialCaseForA(state.a, action, state.b), b: sliceReducerB(state.b, action) } } default: return state } } function rootReducer(state, action) { const intermediateState = combinedReducer(state, action) const finalState = crossSliceReducer(intermediateState, action) return finalState } ``` 已經有一個庫 [reduce-reducers](https://github.com/acdlite/reduce-reducers) 可以簡化以上操作流程。它接收多個 reducer 然后對它們依次執行 `reduce()` 操作,并把產生的中間值依次傳遞給下一個 reducer: ```js // 與上述手動編寫的 `rootReducer` 一樣 const rootReducer = reduceReducers(combinedReducers, crossSliceReducer) ``` 值得注意的是,如果你使用 `reduceReducers` 你應該確保第一個 reducer 能夠定義初始狀態的 state 數據,因為后續的 reducers 通常會假定 state 樹已經存在,也就不會為此提供默認狀態。 ## 更多建議 再次強調,Reducer *只是*普通的函數,明確這一概念非常重要。`combineReducers` 雖然實用也只是冰山一角。除了用 switch 語句編寫函數,還可以用條件邏輯;函數不僅可以彼此組合,也可以調用其他函數。也許你可能需要這樣的一個 reducer,它既能夠重置 state,也能夠響應特定的 action。你可以這樣做: ```js const undoableFilteredSliceA = compose( undoReducer, filterReducer('ACTION_1', 'ACTION_2'), sliceReducerA ) const rootReducer = combineReducers({ a: undoableFilteredSliceA, b: normalSliceReducerB }) ``` 注意 `combineReducers` 無需知道也不關心任何一個負責管理 `a` 數據的 reducer。所以我們并不需要像以往一樣修改 `combineReducers` 來實現撤銷功能 —— 我們只需把各種函數組合成一個新函數即可。 另外 `combineReducers` 只是 Redux 內置的 reducer 工具,大量形式各異的可復用的第三方 reducer 工具層出不窮。在 [Redux Addons 目錄](https://github.com/markerikson/redux-ecosystem-links)中列舉了很多可供使用的第三方工具。也許這些工具解決不了你的應用場景,但你隨時都可以實現一個能夠滿足你需求的工具函數。
                  <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>

                              哎呀哎呀视频在线观看