这里只是最简单的使用方法
前提知识
- store:整个应用只有一个store,redux提供createStore方法来创建store
- state:是store中的数据,是只读的,可以通过:store.getState()获取,修改方法是触发action
- action:用于告诉redux需要更改state,action出来的对象必须包含type属性,表明action名称
- dispatch:用于将action传递给reducer,是view沟通store的唯一方式!一般在view上调用dispacth,传一个ation过去
- reducer:接收action和state,根据不同的action处理state,并返回一个新的state,必须是纯函数(只要是同样的输入,必定得到同样的输出)
- subscribe:用于监听state的状态变化并执行回调函数。store.subscribe(callback)方法返回一个函数,调用这个函数就可以解除监听,只要把 View 的更新函数(对于 React 项目,就是组件的render方法或setState方法)放入listen,就会实现 View 的自动渲染。
实践流程
普通来讲,如果是同步请求:
- 定义action
function addAge(id) {
return {
type: 'ADD_AGE',
id
}
}
- 定义reducer
const defaultState = {name:"",age:0,id:""};
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD_AGE':
// 省略处理逻辑
return {...state,age:state.age+1};
default:
return state;
}
};
- 创建store
import { createStore } from 'redux';
const store = createStore(reducer);
- 页面调用
export default function App() {
const [state, setState] = useState({});
useEffect(() => {
return Store.subscribe(() => {
setState(Store.getState()); // 订阅时,注册了一个回调函数,每次状态更新,该函数会被自动调用
});
}, []);
function click() {
Store.dispatch(addAge("123"));
}
return(<>{state}</>)
}
在异步情况中,需要使用中间件,因为:dispatch一个action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware。你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
- 引入中间件redux-thunk
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
// 该中间件可以让原来的dispatch接收的由对象变为函数
// 如果是对象就正常接收并发送给reducer,如果是函数则执行函数
const store = createStore(
reducers,
applyMiddleware(thunk)
);
- 写services.js,定义API结构,如
export function getInfo(name){
return Axios.get('/test?name='+name);
}
- 定义一个异步action,返回一个函数,入参是dispatch
const GET_INFO = '获取信息';
const getInfo = async name => dispatch =>{
// 逻辑省略
getInfo(name).then(res=>dispatch({
type: 'GET_INFO ',
info:res
})
}
其他的都一样
react-redux
只在view层不一样:新增两个函数,含义就是字面意思
- mapStateToProps
- mapDispatchToProps
新增一个高阶函数:connect(mapStateToProps,mapDispatchToProps),返回一个函数,将组件传入返回的函数可以获得被包装后的组件!
使用方法:
import React from "react";
import { connect } from "react-redux";
import { Action01, Action02 } from "../../actions/Demo01";
function Demo_01(props) {
return (
<div>
demo_01
<div></div>
<button onClick={() => props.action01("bt1")}>action01</button>
<button onClick={() => props.action02("bt2")}>action02</button>
<p>{props.msg}</p>
<p>{props.value}</p>
</div>
);
}
export default connect(
function mapStateToProps(state) {
return {
msg: state.Demo01.msg,
value: state.Demo01.value
};
},
function mapDispatchToProps(dispatch) {
return {
action01: (msg) => dispatch(Action01(msg)),
action02: (value) => dispatch(Action02(value))
};
}
)(Demo_01);
合并多个reducer并提供应用初始状态
使用combineReducers中间件来合并多个reducer,用于划分状态
import { createStore, combineReducers, applyMiddleware } from "redux";
import ReduxThunk from "redux-thunk";
import Demo01Reducer from "../reducers/Demo01";
import Demo02Reducer from "../reducers/Demo02";
import Demo01State from "../state/Demo01";
import Demo02State from "../state/Demo02";
const allReducers = combineReducers({
Demo01: Demo01Reducer
Demo02: Demo02Reducer
});
export default createStore(
allReducers,
{
Demo01: Demo01State,
Demo02: Demo02State
},
applyMiddleware(ReduxThunk)
);