Appearance
redux的基本使用
store/index.js
JavaScript
import { createStore } from 'redux';
import _ from '@/assets/utils';
// REDUCER
let initial = {
supNum: 0,
oppNum: 0
};
const reducer = function reducer(state = initial, action) {
//防止直接操作原始状态对象向
state = _.clone(true, state);
let { type, payload = 1 } = action;
switch (type) {
case 'VOTE_SUP':
state.supNum += payload;
break;
case 'VOTE_OPP':
state.oppNum += payload;
break;
default:
}
return state;
};
// 创建容器
const store = createStore(reducer);
export default store;
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
ThemeContext.js
JavaScript
import { createContext } from 'react';
const ThemeContext = createContext();
export default ThemeContext;
1
2
3
2
3
index.js
JavaScript
import ThemeContext from './ThemeContext';
import store from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ThemeContext.Provider
value={{
store
}}>
<Vote />
</ThemeContext.Provider>
);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
views/Vote.jsx
jsx
import React, { useContext, useState, useEffect } from 'react';
import VoteMain from './VoteMain';
import VoteFooter from './VoteFooter';
import './Vote.less';
import ThemeContext from '@/ThemeContext';
const Vote = function Vote() {
const { store } = useContext(ThemeContext);
let { supNum, oppNum } = store.getState();
// 控制视图更新的办法加入到redux事件池中
let [_, setRandom] = useState(0);
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setRandom(Math.random());
});
}, []);
return <div className="vote-box">
<header className="header">
<h2 className="title">React真的很不错!!</h2>
<span className="num">{supNum + oppNum}人</span>
</header>
<VoteMain />
<VoteFooter />
</div>;
};
export default Vote;
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
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
views/VoteMain.jsx
jsx
import React, { useContext, useState, useEffect } from 'react';
import ThemeContext from '@/ThemeContext';
const VoteMain = function VoteMain() {
const { store } = useContext(ThemeContext);
let { supNum, oppNum } = store.getState();
let [_, setRandom] = useState(0);
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setRandom(Math.random());
});
}, []);
return <div className="main">
<p>支持人数:{supNum}人</p>
<p>反对人数:{oppNum}人</p>
</div>;
};
export default VoteMain;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
views/VoteFooter.jsx
jsx
import React, { useContext } from 'react';
import ThemeContext from '@/ThemeContext';
const VoteFooter = function VoteFooter() {
const { store } = useContext(ThemeContext);
return <div className="footer">
<button onClick={() => {
store.dispatch({
type: 'VOTE_SUP',
payload: 10
});
}}>支持</button>
<button onClick={() => {
store.dispatch({
type: 'VOTE_OPP'
});
}}>反对</button>
</div>;
};
export default VoteFooter;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21