React实战-通过ToDo源码分析Redux的数据模型设计

来源:互联网 发布:android 棋牌 源码 编辑:程序博客网 时间:2024/06/02 04:23

React实战-通过ToDo源码分析Redux的数据模型设计

计算机技术的本质是数据处理,在各种编程语言、编程框架中,数据模型都是首要考虑的事情。我们都知道在Redux中采用的是单一数据模型,整个应用中只存在store中唯一的state数据对象。但是如何在这个原则下设置自己的数据模型,细则的处理方式依然需要进一步分析。

1.程序中对数据的处理主要方式:

a.对单一数据对象操作

b.获取数据集

c.对数据集中某个数据进行操作

d.添加数据对象到数据集中

2.Redux中的数据处理方式

Redux中采用的是单一state数据对象,所有的操作都只获得同一个state数据对象。

我们在学习的新语言和框架是,第一手资料还是其官网提供的源码、例子和文档,至于翻译或者第三者的总结,大多还是只作为快速入门的方式。

3.ToDo的数据模型

以官网例子中ToDo为例,通过查看源码,我们基本可以摸清Redux的数据处理模型。

ToDostate数据结构是这样的:

State = {

 visibleTodoFilter: 'SHOW_ALL',

   todos: [

     {

       text: 'Read the docs.',

       complete: false

     }

...........

   ]

 }

state的一级子元素存在两个

a.visibleTodoFilter(列表显示筛选条件)

b.Todostodo的列表)

state数据的操作大致也分为两类:

a.设置visibleTodoFilter的筛选条件

b.todos数据集操作

4.ToDo的数据操作方式

由于Redux是单一state,并且为函数式编程。你每次操作后均要返回同一个state。我们对visibleTodoFiltertodos的操作可以采用以下方式。

a.reducers中操作visibleTodoFilter的结果

function todoApp(state = initialState, action) {

  switch (action.type) {

    case SET_VISIBILITY_FILTER:

      return Object.assign({}, state, {

        visibilityFilter: action.filter

      })

    default:

      return state

  }

}

需要注意的是返回结果为:Object.assign({}, state, {

        visibilityFilter: action.filter

      })

b.reducers中操作todos的结果

function todoApp(state = initialState, action) {

  switch (action.type) {

    case ADD_TODO:

      return Object.assign({}, state, {

        todos: [

          ...state.todos,

          {

            text: action.text,

            completed: false

          }

        ]

      })    

}

同样需要注意的是返回值。

以上数据的操作,基本上可以看出Redux的数据操作方式,在对visibilityFiltertodos操作时,我们采用的是Object.assign复制原有state值,然后将新的数据变化加入到state的某个子元素中,使得做任何操作时都只对本操作相关的数据进行更改,而不影响其他数据。

5.ReduxcombineReducers简化数据层次结构处理

从上面的例子可以看到Redux的数据操作方式,但是我们也看出了数据操作的不便,虽然对于整个应用的数据模型结构我们确实需要在编程前就设计好,安排state的数据结构。但是在对每个子元素就行数据操作时,返回结果总是要维护返回的数据结构,让编程变的复杂,也容易出错。combineReducers为我们解决了这个烦恼,使得我们在操作某一个子数据对象时,不用关心state的整体结构。

上面的两个操作可以简化为以下两种方式

a.visibilityFilter的处理方式

function visibilityFilter(state = SHOW_ALL, action) {

  switch (action.type) {

    case SET_VISIBILITY_FILTER:

      return action.filter

    default:

      return state

  }

}

b.todos的处理方式

function todos(state = [], action) {

  switch (action.type) {

    case ADD_TODO:

      return [

        ...state,

        {

          text: action.text,

          completed: false

        }

      ]

    case TOGGLE_TODO:

      return state.map((todo, index) => {

        if (index === action.index) {

          return Object.assign({}, todo, {

            completed: !todo.completed

          })

        }

        return todo

      })

    default:

      return state

  }

}

从以上两段代码可以看出,参数state已经不再是全局的state,而是每个子元素的state,在返回的结果中,我们也不用维护全局的state结果,只返回本子元素的state即可。

而这种便利完全靠combineReducers实现的,通过combineReducers将所有子元素构建成一个完整的state

const todoApp = combineReducers({

  visibilityFilter,

  todos

})

好了,到目前为止,我们可以将构建state数据结构交给combineReducers,在操数据时,我们只关心自己相关的子元素,无需再考虑整个数据结构树了。

0 0
原创粉丝点击