Redux 是 JavaScript 状态容器(是JS库,并不是react的插件库,只不过是经常与react搭配开发,redux同样适用与vue、angular等框架搭配开发),提供可预测化的状态管理,集中式管理多组件共享状态。学过vue的同学,应该接触过vuex,redux就相当于vuex。
安装稳定版:
npm install --save redux
Redux 可以用这三个基本原则来描述:
在src文件夹下创建store文件夹,并分别创建index.js和reducer.js文件。
在index文件中创建store,创建store的时候需要传入一个reducer,这是为了,每次store.dispatch发送一个新的action后,redux都会自动调用reducer,并返回新的state。
import { createStore } from 'redux'
const store = createStore(reducer)
export default store
在reducer文件中创建reducer,reducer就是用来计算新的store的,reducer接收两个参数:当前的state和接收到的action,它会经过计算,然后返回一个新的state。我们不能直接更改state,必须通过返回一个新的state来进行变更。
但是在reducer第一次执行的时候,store传的state是undefined,所以准备了一个initialState作为默认值,复制给state,然后再把这个state返回给store,所以initialState实际上,就是store的初始值。
const initialState = { num: 0 };
const reducer = (prevState = initialState, action) => {
let newState = {...prevState}
switch (action.type) {
case 'ADD':
newState.num = 1
return newState;
default:
return prevState;
}};
// reducers.js,不同的reducer函数
export default theDefaultReducer = (state = 0, action) => state;
export const firstNamedReducer = (state = 1, action) => state;
export const secondNamedReducer = (state = 2, action) => state;
// rootReducer.js
import {combineReducers, createStore} from "redux";
import theDefaultReducer, {firstNamedReducer, secondNamedReducer} from "./reducers";
// 使用 ES6 的对象字面量简写方式定义对象结构
const rootReducer = combineReducers({
theDefaultReducer,
firstNamedReducer,
secondNamedReducer
});
// 合并为大的rootReducer函数
const store = createStore(rootReducer);
console.log(store.getState());
// {theDefaultReducer : 0, firstNamedReducer : 1, secondNamedReducer : 2}
每个 action 必须有一个 type 属性,这表示 action 的名称,然后还可以有一个 payload 属性,这个属性可以带一些参数,用作 Store 变更。
const action = {
type: 'ADD_ITEM',
payload: 'theme', // 可选属性
}
// 在store下创建actionTypes文件,里面定义types的常量并导出
export const SWITCH_THEME = 'switch_theme';
// 在用到action的type的地方,引入刚才定义的常量
import { SWITCH_THEME } from './store/actionTypes';
// 使用的时候,直接用常量代替字符串
handleBtnClick(e){
const action = {
type:SWITCH_THEME
}
store.dispatch(action);
}
// 在store下创建actionCreators.js文件,我们把action的创建统一放到这个文件里,对action进行统一的管理
// 主要是为了提高代码的可维护性,方便自动化测试
import { SWITCH_THEME } from './actionTypes';
// 定义一个常量,是一个函数,该函数返回一个对象,对象包含action的type和值
export const switchTheme = (theme) => ({
type: SWITCH_THEME,
payload: theme,
})
// 具体的使用,先引入这些actionCreators 里的action
import { switchTheme } from './store/actionCreators';
// 然后使用store.dispatch去触发action
handleBtnClick(e){
const action = switchTheme(‘dark’);
store.dispatch(action);
}
在reducer中,action是一个普通的js对象,这种形式叫做同步action,通过store.dispatch()进行分发,但当action为异步的时候,reducer就无法处理,这时,就需要redux-thunk中间件。
安装:
npm install redux-thunk
配置:
import thunkMiddleware from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux'
const store = createStore(reducer, applyMiddleware(thunkMiddleware))
export default store
action函数:
function getAdd(){
return dispatch => {
dispatch({
type: ADD,
payload: axios.get(
url: ADD_URL,
query: {
name: '',
},
)
});
},
}
redux提供了redux-devtools-extension插件,可以对状态变化进行可视化查看
安装:
npm install redux-devtools-extension
同时在chrome浏览器安装Redux DevTools扩展程序
配置代码:
const { createStore } = require('redux');
// 引入工具插件
const { composeWithDevTools } = require('redux-devtools-extension');
const store = createStore(reducer, composeWithDevTools(// 包裹在中间件外部));
在浏览器中按f12,找到Redux菜单,点击便可以看到:
createStore 创建store
store.dispatch(),派发创建的action
store.getState(),获取到store里的数据内容
store.subscribe(),订阅store里数据的改变,只要store发生改变,subscribe方法接收的函数,就会被执行。