从零开始搭建一个react项目开发(11)
Action Creators
Action creators 是创建acitons并传递给reducer的函数,它通常返回一个action对象,有时候借用thunk这样的中间件也可以返回dispatch多个actions,在我们的app中为了简化暂时不涉及这个模式。
function addItem(item){ return { type: ADD_ITEM, item // this is new ES6 shorthand for when the key is the same as a variable or perameter within the scope of the object. It's the same as item: item } }
Reducers
reducer是唯一可以触碰store的元素,初始值为initialState,形式上就是一个简单的switch语句,但是注意不能直接改变state,因为state是immutable。也就是说我们不能直接使用.pop or .push这些方法操作数组。
下面是示例代码:
const initialState = { list: [] }; export default function reducer(state = initialState, action){ switch (action.type){ case ADD_ITEM: return Object.assign( {}, state, { list: [...state.list, action.item]} // here we see object.assign again, and we're returning a new state built from the old state without directly manipulating it ) default: return state; } }
概念已经介绍完毕,下面开始将原来的功能逻辑用redux重写。
1. Initial state
首先我们在 src/redux/modules/toDoApp中声明initialState。
const initialState = { list: [{item: 'test', done: false}] // just added this to test that state is being passed down propperly, newToDo: '' }; export default function reducer(state = initialState, action){ switch (action.type){ default: return state; } }
现在在 ToDoApp.js的 render() 方法中return之前添加console.log(this.props) 会打印出下面的对象:
toDoApp: Object list: Array[1] 0: "test" length: 1 __proto__: Array[0] __proto__: Object __proto__: Object
测试通过,我们就可以传递这些数据给子组件了,这里就可以把原来List组件的 listItems prop和Input的value prop替换掉了。
<List onClick={this.onListItemClick} listItems={this.props.toDoApp.list} deleteListItem={this.deleteListItem} /> <Input value={this.props.toDoApp.newToDo} onChange={this.onInputChange} onSubmit={this.onInputSubmit} />
这里只是替换掉了数据,下面还需要把action也替换。
3. Input action
这个过程就是把我们原来在ToDoApp 组件的行为逻辑全部迁移到redux文件夹下的 toDoApp module中去。
const INPUT_CHANGED = 'INPUT_CHANGED'; export function inputChange(newToDo){ return { type: INPUT_CHANGED, newToDo } }
然后在reducer的switch中新增如下处理: