1.一张图了解redux
- createStore(【reducer管理员】,【preloadedstate初始状态】)
- reducer函数=>根据不同的type标识,修改不同信息
- store.getState()
- store.subscribe([方法])
- store.dispatch({type:xxx,xxx:xxx})

2.把某个方法增加到STORE的事件池中;当STORE容器中的状态改变,通知此方法执行,此方法可以把当前组件重新渲染;
=> 方法中获取最新的STORE容器中的状态,基于SETSTATE方法控制视图的重新渲染;
应用
- 引入 createStore => import { createStore } from 'redux';
- 创建容器 const store = createStore(reducer,preloadState); preloadState:初始状态值
- 写好reducer 函数function (state = {n: 0,m: 0}, action) state:现在STORE容器中的状态信息 action:DISPATCH派发的行为对象(必然有一个TYPE行为标识) 在reducer第一次执行的时候,容器中状态没有,我们设置初始值(我们一般在reducer中设置,而不是在createStore的preloadState中设置,这样可以设置每个模块的初始状态)
import { createStore } from 'redux';
const reducer = function (state = {
supNum: 0,
oppNum: 0
}, action) {
// 为了防止现在的操作和之前的STATE用同一个堆,我们把STATE最好克隆一份再操作
state = JSON.parse(JSON.stringify(state));
let n = action.n || 1;
switch (action.type) {
case 'CHANGE_SUP':
state.supNum += n;
break;
case 'CHANGE_OPP':
state.oppNum += n;
break;
}
return state;
};
const store = createStore(reducer);
ReactDOM.render(<>
<Vote store={store} />
</>, document.getElementById('root'));
组件
import React from 'react';
function VoteContent(props) {
// 把redux中的状态赋值给组件的私有状态
let store = props.store,
{ supNum, oppNum } = store.getState();
return <>
<p>支持能:{supNum}</p>
<p>支持不能:{oppNum}</p>
</>;
}
function VoteButton(props) {
let store = props.store;
return <>
<button onClick={ev => {
store.dispatch({
type: 'CHANGE_SUP',
n: 10
});
}}>能</button>
<button onClick={ev => {
store.dispatch({
type: 'CHANGE_OPP'
});
}}>不能</button>
</>;
}
class Vote extends React.Component {
/*
* 获取REDUX中的状态信息 GET-STATE
* 向REDUX事件池中追加方法(目的:容器中状态改变,执行这个方法,控制当前组件重新渲染)SUB-SCRIBE
*/
render() {
let store = this.props.store,
{ supNum, oppNum } = store.getState();
return <div>
<h3>今天天气真好 <span>N:{supNum + oppNum}</span></h3>
<VoteContent store={store} />
<VoteButton store={store} />
</div>;
}
componentDidMount() {
// subscribe的返回值是才事件池中移除方法的函数:unsubscribe()
let unsubscribe = this.props.store.subscribe(() => {
this.forceUpdate();
});
}
}
2.redux的工程化开发
项目构建框架
|-src
|-api
|-assets 静态资源
|-conmponents 公共组件
|-pages 各个页面
|-routes 路由
*|-store 公共管理状态
*|-reducer
|-voteReducer.js vote板块的reducer
|-personalReducer.js 个人中心板块的reducer
|-index.js 把每一个模块的reducer进行合并
*|-action 把dispatch派发时需要的action对象管理起来
|-voteAction.js vote板块的action对象管理
|-index.js 合并后的action
*|-index.js** 创建STORE
*|-action-types.js** 派发行为类型的宏观管理
*|-index.js 入口
演示
- store/index.js
import {
createStore
} from 'redux';
import reducer from './reducer/index';
const store = createStore(reducer);
export default store;
- 每个REDUCER都管理自己单独的状态(示例)
import * as TYPES from '../action-types';
const initialState = {
supNum: 10,
oppNum: 5
};
export default function voteReducer(state = initialState, action) {
state = JSON.parse(JSON.stringify(state));
switch (action.type) {
case TYPES.VOTE_CHANGE_SUPNUM:
state.supNum++;
break;
case TYPES.VOTE_CHANGE_OPPNUM:
state.oppNum++;
break;
}
return state;
};
- 合并reducer
import {combineReducers} from 'redux';
import voteReducer from './voteReducer';
import personalReducer from './personalReducer';
export default combineReducers({
vote: voteReducer,
personal: personalReducer
});
- combineReducers处理后的结果:按照模块划分状态
{
vote: {
supNum: 10,
oppNum: 5,
},
personal: {
supNum: 0,
info: {}
}
}
store.getState().vote.supNum
- 每个ACTION也是单独的(示例)
import * as TYPES from '../action-types';
export default {
changeSupNum() {
return {
type: TYPES.VOTE_CHANGE_SUPNUM
};
},
changeOppNum() {
return {
type: TYPES.VOTE_CHANGE_OPPNUM
};
}
};
合并action
import voteAction from './voteAction';
import personalAction from './personalAction';
export default {
vote: voteAction,
personal: personalAction
};
小小应用
//=>index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Vote from './Vote';
import store from './store/index';
ReactDOM.render(<>
<Vote store={store} />
</>, document.getElementById('root'));
//======> vote.jsx
import React from 'react';
import actions from './store/actions/index';
function VoteContent(props) {
let { supNum, oppNum } = props.store.getState().vote;
return <>
<p>支持能:{supNum}</p>
<p>支持不能:{oppNum}</p>
</>;
}
function VoteButton(props) {
let store = props.store;
return <>
<button onClick={ev => {
store.dispatch(actions.vote.changeSupNum());
}}>能</button>
<button onClick={ev => {
store.dispatch(actions.vote.changeOppNum());
}}>不能</button>
</>;
}
class Vote extends React.Component {
constructor(props) {
super(props);
// 把REDUX容器中的公共状态赋值给自己的私有状态
let { vote: { supNum, oppNum } } = this.props.store.getState();
this.state = {
supNum,
oppNum
};
}
render() {
let { supNum, oppNum } = this.state,
store = this.props.store;
return <div>
<h3>今天天气真好! <span>N:{supNum + oppNum}</span></h3>
<VoteContent store={store} />
<VoteButton store={store} />
</div>;
}
// 第一次渲染完,把REDUX状态改变后重新渲染组件的方法增加到事件池中
componentDidMount() {
this.props.store.subscribe(() => {
this.setState({
...this.props.store.getState().vote
});
});
}
}
export default Vote;