ActionTypes 的拆分
之前的代码中我们把每一个action 都 定义一个type,然后再到 reducer 里面判断这些type 。这样子,万一马虎了,就很难排错,也会不太好维护。
我们可以将 type 都放到一起。
在src/store 下,建立文件 actionType.js 。
然后写入下面内容。
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
然后在reducer.js中引入,并使用:同理,处理 组件, 就不贴了。
import {
CHANGE_INPUT_VALUE,
ADD_TODO_ITEM,
DELETE_TODO_ITEM
} from './actionTypes';
const defaultState = {
inputValue: '123',
list: []
};
// reducer 可以接受 state ,但是不能修改state
export default (state = defaultState, action) => {
if (action.type === CHANGE_INPUT_VALUE) {
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value;
return newState;
}
if (action.type === ADD_TODO_ITEM) {
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = '';
return newState;
}
if (action.type === DELETE_TODO_ITEM) {
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index, 1);
return newState;
}
return state;
}
使用 actionCreator 统一创建 action
之前我们都是分散在各个业务逻辑里创建 action,再使用store 的dispatch 函数。当业务逻辑非常复杂的时候,这样就不好管理维护了。一般,会通过actionCreator 来统一管理、创建页面上所有的action。
我们在src/store 目录下,新建文件 actionCreators.js 。代码如下。
import {
CHANGE_INPUT_VALUE,
ADD_TODO_ITEM,
DELETE_TODO_ITEM
} from './actionTypes';
export const getInputChangeAction = (value) => ({
type: CHANGE_INPUT_VALUE,
value
})
export const getAddItemAction = () => ({
type: ADD_TODO_ITEM
})
export const getDeleteItemAction = (index) => ({
type: DELETE_TODO_ITEM,
index
})
然后再在todolist.js 中引用并使用。代码如下。
import React, {Component} from 'react';
import 'antd/dist/antd.css';
import { Input, Button, List } from 'antd';
import store from './store/index.js';
import {
getInputChangeAction,
getAddItemAction,
getDeleteItemAction
} from './store/actionCreators';
class BeautifulToDoList extends Component {
constructor(props) {
super(props);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleBtnClick = this.handleBtnClick.bind(this);
store.subscribe(this.handleStoreChange);
}
render() {
return (
<div style={{marginTop: '10px',marginLeft: '10px'}}>
<Input
value={this.state.inputValue}
placeholder="todo info"
style={{width: 300, marginRight: '10px'}}
onChange={this.handleInputChange}
/>
<Button
type="primary"
onClick={this.handleBtnClick}
>提交</Button>
<List
style={{marginTop: '10px', width: '300px'}}
bordered
dataSource={this.state.list}
renderItem={(item, index) => (<List.Item onClick={this.handleItemClick.bind(this, index)}>{item}</List.Item>)}
/>
</div>
)
}
handleInputChange(e) {
const action = getInputChangeAction(e.target.value);
store.dispatch(action);
}
handleStoreChange() {
this.setState(store.getState());
}
handleBtnClick() {
const action = getAddItemAction();
store.dispatch(action);
}
handleItemClick(index) {
const action = getDeleteItemAction(index);
store.dispatch(action);
}
}
export default BeautifulToDoList;