第一版
直接在非redux版本上进行改造,未做改动。
index
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import store from "./redux/store";
ReactDOM.render(<App/>,document.getElementById('root'))
store.subscribe(()=>{
ReactDOM.render(<App/>,document.getElementById('root'))
})
store
import countReducer from "./count_reducer";
import {createStore} from "redux";
export default createStore(countReducer);
count_reducer
export default function countReducer(preState = 0, action) {
const {type, data} = action;
switch (type) {
case 'increment':
return preState + data;
case 'decrement':
return preState - data;
default:
return preState;
}
}
Count
import React, {Component} from 'react';
import {Button, Select, Tooltip} from 'antd';
import store from "../redux/store";
const {Option} = Select;
class Count extends Component {
state = {value: 1}
handleChange = (value) => {
this.setState({value: value});
}
calculation = (isInc, isOdd, isSync = false) => {
if (isSync === true) {
setTimeout(() => {
store.dispatch({type: 'increment', data: this.state.value})
}, 500)
return;
}
if (isOdd === true) {
const sum = store.getState();
if (sum % 2 !== 0) {
store.dispatch({type: 'increment', data: this.state.value})
return;
}else{
return;
}
}
if (isInc === true) {
store.dispatch({type: 'increment', data: this.state.value});
return;
} else {
store.dispatch({type: 'decrement', data: this.state.value});
return;
}
}
render() {
const sum = store.getState();
return (
<div>
<Tooltip title="prompt text">
<span>结果为{sum}</span>
</Tooltip>
<br/>
<Select defaultValue={1} style={{width: 120}} onChange={this.handleChange}>
<Option value={1}>1</Option>
<Option value={2}>2</Option>
<Option value={3}>3</Option>
</Select>
<Button type="primary" onClick={() => this.calculation(true, false)}>increase</Button>
<Button type="primary" onClick={() => this.calculation(false, false)}>subtract</Button>
<Button type="primary" onClick={() => this.calculation(true, true)}>increase if odd</Button>
<Button type="primary" onClick={() => this.calculation(true, true, true)}>increase sync</Button>
</div>
);
}
}
export default Count;
总结:
- 使用dispatch目的就是更改state,setState后会直接调用render,但dispatch并不会去调用render,所以我采用了最low的主动停止的做法
- 订阅采用直接订阅整个页面,一定注意的是,这个不会影响性能,因为react内部有diff算法做把控,当然这个方法也很low
第二版
思路:redux其实就是去做state处理的,那么是不是应该所有的逻辑处理都应该给到redux去做,react只做接收渲染就可以了
count_reducer
export default function countReducer(preState = 0, action) {
const {type, subType, data} = action;
switch (type) {
case 'increment':
if (subType === 'odd') {
if (preState % 2 !== 0) {
return preState + data;
} else {
return preState;
}
} else {
return preState + data;
}
case 'decrement':
return preState - data;
default:
return preState;
}
}
Count
import React, {Component} from 'react';
import {Button, Select, Tooltip} from 'antd';
import store from "../redux/store";
const {Option} = Select;
class Count extends Component {
state = {value: 1}
handleChange = (value) => {
this.setState({value: value});
}
calculation = (type, subType) => {
if (subType === 'sync') {
setTimeout(() => {
store.dispatch({type: type, subType: subType, data: this.state.value});
}, 500)
} else {
store.dispatch({type: type, subType: subType, data: this.state.value});
}
}
render() {
const sum = store.getState();
return (
<div>
<Tooltip title="prompt text">
<span>结果为{sum}</span>
</Tooltip>
<br/>
<Select defaultValue={1} style={{width: 120}} onChange={this.handleChange}>
<Option value={1}>1</Option>
<Option value={2}>2</Option>
<Option value={3}>3</Option>
</Select>
<Button type="primary" onClick={() => this.calculation('increment', '')}>increase</Button>
<Button type="primary" onClick={() => this.calculation('decrement', '')}>subtract</Button>
<Button type="primary" onClick={() => this.calculation('increment', 'odd')}>increase if
odd</Button>
<Button type="primary" onClick={() => this.calculation('increment', 'sync')}>increase
sync</Button>
</div>
);
}
}
export default Count;
总结:
- 异步处理无法使用redux,可能是可以使用的,但我没找到办法,如果后续知道方法,会在下面的博客中分享
- 目前知道的是reducer入参自己随意组织,动作可以分解为很多入参,或者给json内部拆解也行
- 就目前知识量而言,用redux应该按这个思路来,所以逻辑代码都应该扔给redux的reducer去做,react就做渲染就可以了