从零开始搭建一个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中新增如下处理:
