在 src/index.js 中添加模拟 redux 时创建的 createStore 函数,并创建一个 themeReducer 用来初始化 state 并维护 state 的更新,通过 themeReducer 生成一个 store。然后将 store 放到 Index 组件的 context 里面,这个每个子组件都可以获取到 store 了。
修改 src/index.js: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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66import React, { Component } from "react";
import PropTypes from "prop-types";
import ReactDOM from "react-dom";
import Header from "./Header";
import Content from "./Content";
import "./index.css";
function createStore(reducer) {
let events = [];
let state = null;
let store = {
subscribe: (event) => events.push(event),
dispatch: (action) => {
state = reducer(state, action);
events.forEach((event) => event());
},
getState: () => state
};
// 初始化state
store.dispatch({});
return store;
}
function themeReducer(state, action) {
if (!state) {
return {
themeColor: "red"
};
}
switch (action.type) {
case "CHANGE_THEME_COLOR":
return { ...state, themeColor: action.themeColor };
default:
return state;
}
}
const store = createStore(themeReducer);
class Index extends Component {
static childContextTypes = {
store: PropTypes.object
};
getChildContext() {
return {
store
};
}
render() {
return (
<div>
<Header />
<Content />
</div>
);
}
}
ReactDOM.render(
<Index />,
document.getElementById("root")
);
然后修改 src/Header.js 和 src/Context.js,让它从 Index 的 context 里面获取 store,并且获取里面的 themeColor 状态来设置自己的颜色。
src/Header.js1
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
41import React, { Component } from "react";
import PropTypes from "prop-types";
class Header extends Component {
static contextTypes = {
store: PropTypes.object
};
state = {
themeColor: ""
};
componentWillMount() {
const { store } = this.context;
// 挂载的时候,进行第一次渲染
this.updateThemeColor();
// 然后订阅 store 的后续变化,并更新
store.subscribe(() => this.updateThemeColor());
}
updateThemeColor() {
let state = this.context.store.getState();
this.setState({
themeColor: state.themeColor
});
}
// static getDerivedStateFromProps(nextProps, prevState) {
//
// }
render() {
return (
<h1 style={{ color: this.state.themeColor }}>React-Redux是什么</h1>
);
}
}
export default Header;
src/Context.js
1 | import React, { Component } from "react"; |
修改 src/ThemeSwitch.js,添加颜色更新及两个按钮的点击事件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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57import React, { Component } from "react";
import PropTypes from "prop-types";
class ThemeSwitch extends Component {
static contextTypes = {
store: PropTypes.object
};
state = {
themeColor: ""
};
componentWillMount() {
let { store } = this.context;
this.updateThemeColor();
store.subscribe(() => {
this.updateThemeColor();
});
}
updateThemeColor() {
const { store } = this.context;
const state = store.getState();
this.setState({ themeColor: state.themeColor });
}
// 更新store中的颜色
handleSwitchColor(color) {
let { store } = this.context;
store.dispatch({
type: "CHANGE_THEME_COLOR",
themeColor: color
});
}
render() {
return (
<div>
<button
style={{ color: this.state.themeColor }}
onClick={this.handleSwitchColor.bind(this, "red")}
>
设置主题颜色red
</button>
<button
style={{ color: this.state.themeColor }}
onClick={this.handleSwitchColor.bind(this, "green")}
>
设置主题颜色green
</button>
</div>
);
}
}
export default ThemeSwitch;
到此 store 和 context 已经结合起来,看起来功能完成的不错,就是代码稍微啰嗦,后面继续优化。