转载请注明出处,未经同意,不可修改文章内容。
🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。
1 怎么创建和使用 actionCreator
之前的代码中,由于只是很简单的需求实现,故将 action 的具体实现“逻辑”,分散在了各个业务逻辑里。
但在稍微复杂点的实际项目中,我们一般会通过 actionCreator 来统一地创建和管理页面上所有 action 的具体实现“逻辑”。
之所以如此,是因为“一个函数尽量只做一件事”这种编码方式,有利于后续代码的测试和维护!
接下来,我们把之前代码中 action 的具体实现“逻辑”,封装到 actionCreator 里边。
1️⃣在 store 目录下创建一个 actionCreators.js 文件:
2️⃣在 actionCreators.js 文件中封装一些“方法”(即,将之前 TodoList.js 中 action 创建的代码,封装到 actionCreators.js 文件里。然后在 TodoList.js 文件中,直接调用封装后的“方法”即可):
// 2️⃣-④:既然下边用到了“常量”,故这里要先引入“常量”;
import {CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM} from "./actionTypes";
export const getInputChangeAction = (value) => ({ /*
2️⃣-①:定义一个方法,
让它等于一个“箭头函数”,并返回一个“对象”;
*/
type: CHANGE_INPUT_VALUE, /*
2️⃣-②:“箭头函数”返回一个 type 属性,
它的值为“常量”CHANGE_INPUT_VALUE;
*/
value // 2️⃣-③:将“接收”的 value 返回出去;
});
// 2️⃣-⑤:同理,封装其他的 action 代码:
export const getAddItem = () => ({
type: ADD_TODO_ITEM
});
export const getAddItemAction = () => ({
type: ADD_TODO_ITEM
});
export const getDeleteItemAction = (index) => ({
type: DELETE_TODO_ITEM,
index
})
3️⃣打开 TodoList.js 文件,在里边去直接“调用”上边创建好的方法:
import React, {Component} from "react";
import 'antd/dist/antd.css';
import { Input, Button, List } from 'antd';
import store from "./store";
// 3️⃣-①:首先,将创建好的“方法”引入;
import {getInputChangeAction, getAddItemAction, getDeleteItemAction} from "./store/actionCreators";
// 3️⃣-⑧:以上几步完成后,下边这行代码在这里就没用了,故删除。
// import {CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM} from "./store/actionTypes";
class TodoList extends Component {
constructor(props) {
super(props);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleButtonClick = this.handleButtonClick.bind(this);
store.subscribe(this.handleStoreChange);
}
render() {
return (
<div style={{marginTop: "10px", marginLeft: "10px"}}>
<div>
<Input
value={this.state.inputValue}
placeholder="todo info"
style={{width: "300px", marginRight: "10px"}}
onChange={this.handleInputChange}
/>
<Button type="primary" onClick={this.handleButtonClick}>提交</Button>
<List style={{marginTop: "10px", width: "300px"}}
bordered
dataSource={this.state.list}
renderItem={(item, index) => <List.Item onClick = {this.handleItemDelete.bind(this, index)}>{item}</List.Item>}
/>
</div>
</div>
)
}
handleInputChange(e) {
/*
3️⃣-②:将以下几行代码删除;
const action = {
type: CHANGE_INPUT_VALUE,
value: e.target.value
}
*/
// 3️⃣-③:直接调用 getInputChangeAction 方法:
const action = getInputChangeAction(e.target.value)
store.dispatch(action);
}
handleStoreChange() {
this.setState(store.getState());
}
handleButtonClick() {
/*
3️⃣-④:将以下几行代码删除;
const action = {
type: ADD_TODO_ITEM
};
*/
// 3️⃣-⑤:直接调用 getAddItemAction 方法;
const action = getAddItemAction();
store.dispatch(action);
}
handleItemDelete(index) {
/*
3️⃣-⑥:将以下几行代码删除;
const action = {
type: DELETE_TODO_ITEM,
index
};
*/
// 3️⃣-⑦:直接调用 getDeleteItemAction 方法;
const action = getDeleteItemAction(index);
store.dispatch(action);
}
}
export default TodoList;
看下页面效果(正常运行):
至此,我们整个 Redux 的开发流程就和之前讲解的图片完全对应上了:
2 对 redux “入门知识”做一个总结
-
store 是唯一的;
-
只有 store 能改变自己的内容;
-
Reducer 必须是“纯函数”(即,给定固定的输入,就一定会有固定的输出,且不会有任何副作用。而,一旦一个函数里有 setTimeout、AJAX 请求、new Date 等“异步”、“时间”相关的操作时,这个函数就不是“纯函数”!);
-
Redux 核心 API:
- createStore
- store.dispatch
- store.getState
- store.subscribe
祝好,qdywxs ♥ you!