npm install --save redux
Redux是将整个应用状态存储到一个地方,称为store,里面保存一棵状态树state tree。组件可以派发(dispatch)行为(action)给store,而不是直接通知其它组件。组件内部通过订阅store中的状态(state)来刷新自己的视图。
subscribe 这个函数是用来去订阅 store 的变化,比如你每次对 store 进行 dispatch(action)都会触发 subscribe 注册的函数调用,这个在实际情况不是必须要的,看自己的应用场景,比如你想监控 store 的全局变化时 可以用 subscript 订阅一下,然后作一些反应
复制代码
下图是非redux方式和redux方式:
redux工作流程:
图解:
redux
dispatch 发送命令
action dispatch发送的命令action
reducer 处理器,处理action ,改变state >------store
state ,被reducer处理器的action命令改变
例:
组件1:发送命令,dispatch---action:{type:'changeColor',color:'red'}
处理器收到action后改变state
其他组件根据state刷新自己
复制代码
redux实现步骤:
1 创建仓库,存储state 和 reducer 获取最新状态 向仓库发送action 订阅仓库内的状态变化(订阅完成后取消订阅)
一个简单的例子:
//redux.js 封装的redux库
/**
* redux跟react并没必然的关系
* createStore 创建仓库
**/
//let {createStore} = require('redux');
let createStore = (reducer) => {
let state;//定义初始状态
let getState = () => state;//用来获取最新的状态
let listeners = [];//监听函数数组
//向仓库发关action
let dispatch = (action) => {
//传入老状态和本次的action,返回新状态
state = reducer(state,action);
//通知所有的监听者,让所有的监听函数依次执行
//依次调用所有的订阅函数
listeners.forEach(listener=>listeners());
}
//订阅仓库内的状态变化事件,当状态发生变化后会监听函数
//订阅方法执行后会返回一个取消订阅的函数,调用它订阅
let subscribe = listener =>{
listeners.push(listener);
//订阅方法执行后会返回一个取消订阅的函数,调用它订阅
return ()=>{
listeners = listeners.filter(l=>listener!==l);
}
}
//在创建仓库的时候就直接派发一次空的action,确保state有初始值
dispatch({});
return {
getState, //获取最新的状态对象
subscribe, //原来订阅状态变化事件
dispatch //发身action
}
}
export {createStore}
复制代码
//index.js
import {createStore} from './1.redux'
import $ from 'jquery'
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE'
$('#body').append(`
<p id="counter"></p>
<button id="increaseBtn">+</button>
<button id="decreaseBtn">-</button>
`);
//state是状态树,可以是任意的结构
//action是一个纯对象{type:'INCREASE',amount:2} {type:'DECREASE'}
let reducer = (state = {number:0},action)=>{
if(action === undefined) return state;
switch(action.type){
case INCREASE:
return {number:state.number+action.amount};
case DECREASE:
return {number:state.number-action.amount};
default:
return state;
}
}
//调用仓库
let store = createStore(reducer);
console.log(store.getState());//undefined 需要执行一次dispatch
let render = ()=>{
$('#counter').html = store.getState().number;
}
//当仓库里的state发生变化的时候,会重新执行render,读取最新的状态数据并更新视图
//订阅
store.subscribe(render);
//点击函数的时候,发身一个INCREASE的action,会得到一个新的state,
$('#increaseBtn').click(()=>store.dispatch({type:INCREASE,amount:3}));
$('#decreaseBtn').click(()=>store.dispatch({type:DECREASE,amount:2}));
render();
复制代码