不要修改 state。 使用 Object.assign() 新建了一个副本

不要修改 state。 使用 Object.assign() 新建了一个副本。不能这样使用 Object.assign(state, { visibilityFilter: action.filter }),因为它会改变第一个参数的值。你必须把第一个参数设置为空对象。你也可以开启对 ES7 提案对象展开运算符的支持, 从而使用 { ...state, ...newState } 达到相同的目的。

在 default 情况下返回旧的 state。遇到未知的 action 时,一定要返回旧的 state。

Object.assign 须知

Object.assign() 是 ES6 特性,但多数浏览器并不支持。你要么使用 polyfill,Babel 插件,或者使用其它库如 _.assign() 提供的帮助方法。

switch 和样板代码须知

switch 语句并不是严格意义上的样板代码。Flux 中真实的样板代码是概念性的:更新必须要发送、Store 必须要注册到 Dispatcher、Store 必须是对象(开发同构应用时变得非常复杂)。为了解决这些问题,Redux 放弃了 event emitters(事件发送器),转而使用


最后,TOGGLE_TODO 的实现也很好理解:

case TOGGLE_TODO:

  return Object.assign({}, state, {

    todos: state.todos.map((todo, index) => {

      if (index === action.index) {

        return Object.assign({}, todo, {

          completed: !todo.completed

        })

      }

      return todo

    })

  })

我们需要修改数组中指定的数据项而又不希望导致突变, 因此我们的做法是在创建一个新的数组后, 将那些无需修改的项原封不动移入, 接着对需修改的项用新生成的对象替换。(译者注:Javascript 中的对象存储时均是由值和指向值的引用两个部分构成。此处突变指直接修改引用所指向的值, 而引用本身保持不变。) 如果经常需要这类的操作,可以选择使用帮助类 React-addons-update,updeep,或者使用原生支持深度更新的库 Immutable。最后,时刻谨记永远不要在克隆 state 前修改它。


import { combineReducers } from 'redux'

const todoApp = combineReducers({

visibilityFilter,

todos

})

export default todoApp

注意上面的写法和下面完全等价:

export default function todoApp(state = {}, action) {

return {

visibilityFilter: visibilityFilter(state.visibilityFilter, action),

todos: todos(state.todos, action)

}

}

你也可以给它们设置不同的 key,或者调用不同的函数。下面两种合成 reducer 方法完全等价:

6 2019/1/5 0:35:38

对象建和值命名一样时可以简写一个就行

0:47:05

6 2019/1/5 0:47:05

import { connect } from 'react-redux'

import { setVisibilityFilter } from '../actions'

import Link from '../components/Link'

const mapStateToProps = (state, ownProps) => {

return {

active: ownProps.filter === state.visibilityFilter

}

}

const mapDispatchToProps = (dispatch, ownProps) => {

return {

onClick: () => {

dispatch(setVisibilityFilter(ownProps.filter))

}

}

}

const FilterLink = connect(

mapStateToProps,

mapDispatchToProps

)(Link)

你可能感兴趣的:(不要修改 state。 使用 Object.assign() 新建了一个副本)