关闭

React Native之Redux使用详解之Reducers(30)

1918人阅读 评论(0) 收藏 举报
分类:

React Native之Redux使用详解之Reducers

一. Reducers

Actions 描述发生了什么,但不能指定响应中state怎么变化,这是Reducers的工作。

1. 设计State Shape

在Redux中,所有state存储为一个单一对象。写任何代码之前考虑好它的 Shape是一个好的注意。

对于我们的 todo 应用,我们想去存储两种不同事物:

  • 当前所选的可见性过滤器
  • todos 实际列表

你会发现在这个state树中你需要存储一些数据,以及一些UI状态。但是必须保持数据和 UI 状态分离。

{
    visibilityFilter: 'SHOW_ALL',
    todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}

【注意 Relationships】
复杂应用中,分离不同实体,各个实体相互依赖。官方建议保持你的 state 尽可能规范没有任何重叠。保持每个实体保存在一个带有ID作为key的对象中,通过IDs关联其他实体或者列表。可以假定认为app的state作为数据库。这个方式在normalizr’s 文档。例如,todosById: { id -> todo }

2. 操作Actions

如果现在已经确定好整个App的state对象, 接下来准备为App写一个Reducer. 该Reducer 是一个以前一状态数和一个action作为参数,返回新状态的纯函数.

(previousState,action) => newState

保持reducer纯函数是非常重要,我们不应该在一个reducer中做以下操作:

  • 复制传入的参数
  • 执行副作用操作,如 API 调用和路由转换
  • 调用非纯函数, 如 Date.now()Math.random().

    我将探索如何执行副作用在advanced walkthrough. 目前,我们只需记住reducer必须纯净. 它应该计算下一个状态并返回. No surprises. No side effects. No API calls. No mutations. Just a calculation

我们逐渐写一个reducer, 进而进一步理解之前提到的actions

我们以指定初始化状态开始写程序, Redux 第一次将传入 undefined的state到我们定义的reducer. 这是返回该APP初始化状态的时机.
Show your code:

import { VisibilityFilter} from './actions'

const initialState={
    visibilityFilter: VisibilityFilter.SHOW_ALL,
    todos:[]
}

function todo(state,action) {
  if(typeof state === 'undefined') {
    return initialState;
}

    // For now, don't handle any actions, and just return the state given us.
return state;

}

一巧妙技巧是利用ES6 默认语法(ES6 default arguments syntax) 更简洁的方式去写这段代码.

function todo(state=initialState,action){
// For now, don't handle any actions,and just return the state given to us.
 return state;
}

现在我们来操作 SET_VISIBILITY_FILTER. 我们需要做的就是改变状态visibilityFilter

function todo(state=initialState,action) {
  switch(action) {
    case 'SET_VISIBILITY_FILTER':
    return Object.assign({},state,{
    visibilityFilter:action.filter
    })
    default:
      return state;
    }
}

注意:
1. 我们没有复制state. 而是通过Object.assign()创建一个复制. Object.assign(state, {visibilityFilter: action.filter })是错误写法: 该写法将会复制第一个参数. 你也能学习object spread operator proposal 去写这个 {…state, …newState}.

2.我们返回前一状态在默认case.在一些未知的action情况下,我们需要返回前一状态.

3.Object.assign()
Object.assign()是ES6语法,但是它仍然没有被大多数浏览器实现, 开发者需要利用polyfill去写Babel plugin,或者利用其他的库,如_assign .
4.Note on switch and Boilerplate

The switch statement is not the real boilerplate. The real boilerplate of Flux is conceptual: the need to emit an update, the need to register the Store with a Dispatcher, the need for the Store to be an object (and the complications that arise when you want a universal app). Redux solves these problems by using pure reducers instead of event emitters.

It’s unfortunate that many still choose a framework based on whether it uses switch statements in the documentation. If you don’t like switch, you can use a custom createReducer function that accepts a handler map, as shown in “reducing boilerplate”.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:106187次
    • 积分:1703
    • 等级:
    • 排名:千里之外
    • 原创:68篇
    • 转载:22篇
    • 译文:3篇
    • 评论:11条