# 安装 Redux
npm install redux --save
1
# 创建 store
- 在
src
目录创建store
,然后创建index.js
// /store/index.js
import { createStore } from "redux"; // 引入createStore方法
const store = createStore(); // 创建数据存储仓库
export default store; // 导出
1
2
3
4
2
3
4
- 在
store
文件夹新建一个reducer.js
文件用来管理
// /store/reducer.js
const defaultState = {
inputValue: "Write Something",
list: ["1", "2"],
}; //默认数据
export default (state = defaultState, action) => {
return state;
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 这里可能会报错,原因是
ESlint
,修改一下
// /store/reducer.js
const defaultState = {
inputValue: "Write Something",
list: ["1", "2"],
};
const stateStore = (state = defaultState, action) => {
return state;
};
export default stateStore;
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 接着在
index.js
引入
// /store/index.js
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(reducer)
export default store
1
2
3
4
5
2
3
4
5
# 组件获取 store 的数据
// /src/TodoList.js
import React, { Component } from "react";
import "antd/dist/antd.css";
import { Input, Button, List } from "antd";
import store from "./store";
class TodoList extends Component {
constructor(props) {
super(props);
this.state = store.getState();
console.log(this.state);
}
render() {
return (
<div style={{ margin: "10px" }}>
<div>
<Input placeholder={this.state.inputValue} style={{ width: "250px", marginRight: "10px" }} />
<Button type="primary">增加</Button>
</div>
<div style={{ margin: "10px", width: "300px" }}>
<List bordered dataSource={this.state.list} renderItem={(item) => <List.Item>{item}</List.Item>} />
</div>
</div>
);
}
}
export default TodoList;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 增加 input 响应事件
// /src/TodoList.js
<Input placeholder="Write something" style={{ width: "250px", marginRight: "10px" }} onChange={this.changeInputValue} />
1
2
2
- 在
constructor
进行this
绑定,修改this
的指向,并下写changeInputValue
的方法
// /src/TodoList.js
constructor(props){
super(props)
this.state=store.getState();
this.changeInputValue= this.changeInputValue.bind(this)
}
changeInputValue(e){
console.log(e.target.value)
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 创建 Action
- 想改变
Redux
里边State
的值就要创建Action
了。Action
就是一个对象,这个对象一般有两个属性,第一个是对Action
的描述,第二个是要改变的值 action
创建好后,需要用dispatch()
的方法传给store
// /src/TodoList.js
changeInputValue(e){
const action ={
type:'changeInput',
value:e.target.value
}
store.dispatch(action);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# store 的自动推送策略
store
只是一个仓库,它并没有管理能力,它会把接收到的action
自动转发给Reducer
state
: 指的是原始仓库里的状态。action
: 指的是action
新传递的状态。Reducer
已经拿到了原来的数据和新传递过来的数据,现在要作的就是改变store
里的值。先判断type
是不是正确的,如果正确,我们需要从新声明一个变量newState
。Reducer
里只能接收state
,不能改变state
,所以我们声明了一个新变量,然后再次用return
返回回去
// /store/reducer.js
const stateStore = (state = defaultState, action) => {
if (action.type === "changeInput") {
let newState = JSON.parse(JSON.stringify(state)); // 深度拷贝state
newState.inputValue = action.value;
console.log(state, action);
return newState;
}
return state;
};
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 让组件发生更新
- 现在
store
里的数据已经更新了,但是组件还没有进行更新,我们需要打开组件文件TodoList.js
// /src/TodoList.js
constructor(prors) {
super(prors);
this.state = store.getState();
this.changeInputValue = this.changeInputValue.bind(this);
this.storeChange = this.storeChange.bind(this);
store.subscribe(this.storeChange); // 订阅Redux的状态
}
storeChange(){
this.setState(store.getState())
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 完整代码
- /store/index.js
import { createStore } from "redux"; // 引入createStore方法
import reducer from "./reducer";
const store = createStore(reducer); // 创建数据存储仓库
export default store; //暴露出去
1
2
3
4
2
3
4
- /store/reducer.js
const defaultState = {
inputValue: "Write Something",
list: ["早上4点起床,锻炼身体", "中午下班游泳一小时"],
};
const stateStore = (state = defaultState, action) => {
if (action.type === "changeInput") {
let newState = JSON.parse(JSON.stringify(state)); // 深度拷贝state
newState.inputValue = action.value;
console.log(state, action);
return newState;
}
return state;
};
export default stateStore;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- /src/TodoList.js
import React, { Component } from "react";
import { Input, Button, List } from "antd";
import "antd/dist/antd.css";
import store from "./store/index";
class TodoList extends Component {
constructor(prors) {
super(prors);
this.state = store.getState();
this.changeInputValue = this.changeInputValue.bind(this);
this.storeChange = this.storeChange.bind(this);
store.subscribe(this.storeChange); // 订阅Redux的状态
}
storeChange() {
this.setState(store.getState());
}
changeInputValue(e) {
const action = {
type: "changeInput",
value: e.target.value,
};
store.dispatch(action);
}
render() {
return (
<div style={{ margin: "10px" }}>
<Input placeholder="Write something" style={{ width: "250px", marginRight: "10px" }} onChange={this.changeInputValue} />
<Button type="primary">增加</Button>
<div style={{ marginTop: "10px", width: "300px" }}>
<List bordered dataSource={this.state.list} renderItem={(item) => <List.Item>{item}</List.Item>} />
</div>
</div>
);
}
}
export default TodoList;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40