参考文献 https://www.redux.org.cn/
本文基于官网redux说明,结合实际项目谈一谈redux的使用细节
什么是redux:
redux是react中的全局状态管理体系,相当于vue中的vuex,
是否需要:
在开始使用前,你必须要明确项目是否真的需要它:
1.项目中是否存在多组件共用一种状态的场景?
2.组件之间的状态是否有关联?
举例:添加购物车,显示和修改用户信息,都可以用redux共享全局状态
下面将 以全局添加一个counter为例 来配置redux
怎么使用:
(先来熟悉一下以下几个概念)
1.action:
action 就是一个JavaScript ,当view发生变化时,需要创建action发出通知,让state更新
const action = {
type: 'INCREMENT', //type 代表action的名字,必须保留
text: '我是自定义字段' //除了type外,其他字段名都由你自己的项目需求来决定
}
当然你也可以写成 创建action的方法,方便之后的调用,像这样
export function increment(text) {
return {
type: INCREMENT,
text
}
}
然后在需要在需要用到的地方传给传给 dispatch()
方法即可(dispatch后面会介绍) :
dispatch(increment('我是计数方法'))
附上action.js源码
import { getUserInfo } from '@/apis';
import history from '@/utils/history'
/*
* action 类型
*/
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
export const SET_USER_INFO = 'SET_USER_INFO'
/*
* action 方法
*/
export function increment(text) {
return { type: INCREMENT , text}
}
export function decrement(text) {
return { type: DECREMENT, text}
}
export function addUser(data) {
return { type: SET_USER_INFO, data }
}
2.reducer
官网是这么解释的 :Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的
直接上源码reducer.js
import { combineReducers } from "redux";
import {INCREMENT, DECREMENT, SET_USER_INFO} from './action'
function counter(state = 0, action) { //创建一个计数器reducer
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
default:
return state;
}
}
function userInfo(state = {}, action) { //创建一个用户信息reducer
switch (action.type) {
case SET_USER_INFO:
return action.data;
default:
return state;
}
}
//使用combineReducers集成所有的reducer,之后可以通过store.getState()拿到counter和userInfo
export default combineReducers({
counter,
userInfo
});
3.store
store就是用来管理全局的state
顾名思义,现在我们需要创建store对象,来把之前创建的reducers关联起来
还是直接上源码 index.js 🤭
import { createStore, applyMiddleware } from "redux";
import thunkMiddleware from "redux-thunk";
import { createLogger } from "redux-logger";
import rootReducer from "./reducer";
const loggerMiddleware = createLogger();
export default function configureStore(preloadedState?: any) {
return createStore(
rootReducer,
preloadedState,
applyMiddleware(thunkMiddleware, loggerMiddleware) //中间件的使用,之后再细讲哈,可以先参考官网
);
}
上面三个概念理清后 我们就要在react中关联起来了
4.在react中关联store
在主文件入口 index.js
import ReactDOM from 'react-dom';
import configureStore from "../store"; //引入之前创建的store
import { Provider } from "react-redux";
import history from '@/utils/history'
import { Router, Switch } from "react-router-dom";
const store = configureStore();
const RouterView =
<Provider store={store}>
<Router history={history}> //配置history模式
<Switch>
{renderRoutes(routes)} //路由配置
</Switch>
</Router>
</Provider>
ReactDOM.render(RouterView, document.getElementById("root"));
在相关页面执行相关操作(用connect 关联state的属性和方法)
Home/index.js
import { connect } from 'react-redux'
import React, { Component } from "react";
import { increment } from '@/store/action'
const mapStateToProps = state => {
return {
counter: state.counter
};
}
const mapDispatchToProps = dispatch => {
incrementClick: () => {
dispatch(increment('我是测试text')) //在这里dispatch
}
}
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Button onClick={this.props.incrementClick}>计数增加</Button>
<p>{this.props.counter}</p>
</div>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App) //这里关联
这样全局state下的counter 就被添加到视图中了,当点击计数增加Button时,就会调用对应的dispatch方法,然后更新state里的counter,对应的视图 <p>{this.props.counter}</p> 也随之发生变化
到这里就完成了基本的redux用法,后续再补充再一些深入的学习心得把,有不足之处还请各位指正哦~