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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 管理范式化數據 如 [范式化數據](./NormalizingStateShape.md) 章節所提及的,我們經常使用 Normaizr 庫將嵌套式數據轉化為適合集成到 store 中的范式化數據。但這并不解決針對范式化的數據進一步更新后在應用的其他地方使用的問題。根據喜好有很多種方法可供使用。下面展示一個像文章添加評論的示例。 ## 標準方法 ### 簡單合并 一種方法是將 action 的內容合并到現有的 state。在這種情況下,我們需要一個對數據的深拷貝(非淺拷貝)。Lodash 的 `merge` 方法可以幫我們處理這個: ```javascript import merge from 'lodash/object/merge' function commentsById(state = {}, action) { switch (action.type) { default: { if (action.entities && action.entities.comments) { return merge({}, state, action.entities.comments.byId) } return state } } } ``` 這樣做會讓 reducer 保持最小的工作量,但需要 action creator 在 action dispatch 之前做大量的工作來將數據轉化成正確的形態。在刪除數據項時這種方式也是不適合的。 ### reducer 切片組合 如果我們有一個由切片 reducer 組成的嵌套數據,每個切片 reducer 都需要知道如何響應這個 action。因為我們需要讓 action 囊括所有相關的數據。譬如更新相應的 Post 對象需要生成一個 comment 的 id,然后使用 id 作為 key 創建一個新的 comment 對象,并且讓這個 comment 的 id 包括在所有的 comment id 列表中。下面是一個如何組合這樣數據的例子: > 譯者注:結合上章節中范式化之后的 state 閱讀 ```javascript // actions.js function addComment(postId, commentText) { // 為這個 comment 生成一個獨一無二的 ID const commentId = generateId('comment') return { type: 'ADD_COMMENT', payload: { postId, commentId, commentText } } } // reducers/posts.js function addComment(state, action) { const { payload } = action const { postId, commentId } = payload // 查找出相應的文章,簡化其余代碼 const post = state[postId] return { ...state, // 用新的 comments 數據更新 Post 對象 [postId]: { ...post, comments: post.comments.concat(commentId) } } } function postsById(state = {}, action) { switch (action.type) { case 'ADD_COMMENT': return addComment(state, action) default: return state } } function allPosts(state = [], action) { // 省略,這個例子中不需要它 } const postsReducer = combineReducers({ byId: postsById, allIds: allPosts }) // reducers/comments.js function addCommentEntry(state, action) { const { payload } = action const { commentId, commentText } = payload // 創建一個新的 Comment 對象 const comment = { id: commentId, text: commentText } // 在查詢表中插入新的 Comment 對象 return { ...state, [commentId]: comment } } function commentsById(state = {}, action) { switch (action.type) { case 'ADD_COMMENT': return addCommentEntry(state, action) default: return state } } function addCommentId(state, action) { const { payload } = action const { commentId } = payload // 把新 Comment 的 ID 添加在 all IDs 的列表后面 return state.concat(commentId) } function allComments(state = [], action) { switch (action.type) { case 'ADD_COMMENT': return addCommentId(state, action) default: return state } } const commentsReducer = combineReducers({ byId: commentsById, allIds: allComments }) ``` 這個例子之所有有點長,是因為它展示了不同切片 reducer 和 case reducer 是如何配合在一起使用的。注意這里對 “委托” 的理解。postById reducer 切片將工作委拖給 addComment,addComment 將新的評論 id 插入到相應的數據項中。同時 commentsById 和 allComments 的 reducer 切片都有自己的 case reducer,他們更新評論查找表和所有評論 id 列表的表。 ## 其他方法 ### 基于任務的更新 reducer 僅僅是個函數,因此有無數種方法來拆分這個邏輯。使用切片 reducer 是最常見,但也可以在更面向任務的結構中組織行為。由于通常會涉及到更多嵌套的更新,因此常常會使用 [dot-prop-immutable](https://github.com/debitoor/dot-prop-immutable)、[object-path-immutable](https://github.com/mariocasciaro/object-path-immutable) 等庫實現不可變更新。 ```javascript import posts from "./postsReducer"; import comments from "./commentsReducer"; import dotProp from "dot-prop-immutable"; import {combineReducers} from "redux"; import reduceReducers from "reduce-reducers"; const combinedReducer = combineReducers({ posts, comments }); function addComment(state, action) { const {payload} = action; const {postId, commentId, commentText} = payload; // State here is the entire combined state const updatedWithPostState = dotProp.set( state, `posts.byId.${postId}.comments`, comments => comments.concat(commentId) ); const updatedWithCommentsTable = dotProp.set( updatedWithPostState, `comments.byId.${commentId}`, {id : commentId, text : commentText} ); const updatedWithCommentsList = dotProp.set( updatedWithCommentsTable, `comments.allIds`, allIds => allIds.concat(commentId); ); return updatedWithCommentsList; } const featureReducers = createReducer({}, { ADD_COMMENT : addComment, }; const rootReducer = reduceReducers( combinedReducer, featureReducers ); ``` 這種方法讓 `ADD_COMMENT` 這個 case 要干哪些事更加清楚,但需要更新嵌套邏輯和對特定狀態樹的了解。最后這取決于你如何組織 reducer 邏輯,或許你根本不需要這樣做。 ### Redux-ORM [Redux-ORM](https://github.com/tommikaikkonen/redux-orm) 庫提供了一個非常有用的抽象層,用于管理 Redux store 中存儲的范式化數據。它允許你聲明 Model 類并且定義他們之間的關系。然后它可以為你的數據類型生成新“表”,充當用于查找數據的特殊選擇器工具,并且對數據執行不可變更新。 有幾種方法可以用 Redux-ORM 執行數據更新。首選,Redux-ORM 文檔建議在每個 Model 子類上定義 reducer 函數,然后將自動生成的組合 reducer 函數放到 store 中: ```javascript // models.js import { Model, many, Schema } from 'redux-orm' export class Post extends Model { static get fields() { return { // 定義一個多邊關系 - 一個 Post 可以有多個 Comments, // 字段名是 “comments” comments: many('Comment') } } static reducer(state, action, Post) { switch (action.type) { case 'CREATE_POST': { // 排隊創建一個 Post 實例 Post.create(action.payload) break } case 'ADD_COMMENT': { const { payload } = action const { postId, commentId } = payload // 排隊增加一個 Comment ID 和 Post 實例的聯系 Post.withId(postId).comments.add(commentId) break } } // Redux-ORM 將在返回后自動應用排隊的更新 } } Post.modelName = 'Post' export class Comment extends Model { static get fields() { return {} } static reducer(state, action, Comment) { switch (action.type) { case 'ADD_COMMENT': { const { payload } = action const { commentId, commentText } = payload // 排隊創建一個 Comment 實例 Comment.create({ id: commentId, text: commentText }) break } } // Redux-ORM 將在返回后自動應用排隊的更新 } } Comment.modelName = 'Comment' // 創建 Schema 實例,然后和 Post、Comment 數據模型掛鉤起來 export const schema = new Schema() schema.register(Post, Comment) // main.js import { createStore, combineReducers } from 'redux' import { schema } from './models' const rootReducer = combineReducers({ // 插入 Redux-ORM 自動生成的 reducer,這將 // 初始化一個數據模型 “表”,并且和我們在 // 每個 Model 子類中定義的 reducer 邏輯掛鉤起來 entities: schema.reducer() }) // dispatch 一個 action 以創建一個 Post 實例 store.dispatch({ type: 'CREATE_POST', payload: { id: 1, name: 'Test Post Please Ignore' } }) // dispath 一個 action 以創建一個 Comment 實例作為上個 Post 的子元素 store.dispatch({ type: 'ADD_COMMENT', payload: { postId: 1, commentId: 123, commentText: 'This is a comment' } }) ``` Redux-ORM 庫維護要應用的內部更新隊列。這些更新是不可變更新,這個庫簡化了這個更新過程。 使用 Redux-ORM 的另一個變化是用一個單一的 case reducer 作為抽象層。 ```javascript import { schema } from './models' // 假設這個 case reducer 正在我們的 “entities” 切片 reducer 使用, // 并且我們在 Redux-ORM 的 Model 子類上沒有定義 reducer function addComment(entitiesState, action) { const session = schema.from(entitiesState) const { Post, Comment } = session const { payload } = action const { postId, commentId, commentText } = payload const post = Post.withId(postId) post.comments.add(commentId) Comment.create({ id: commentId, text: commentText }) return session.reduce() } ``` 總之,Redux-ORM 提供了一組非常有用的抽象,用于定義數據類型之間的關系,在我們的 state 中創建了一個 “表”,檢索和反規劃關系數據,以及將不可變更新應用于關系數據。
                  <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>

                              哎呀哎呀视频在线观看