首页 > 专栏 > 前端 > 文章详情
Redux 实现原理浅析 发布于:2021-03-29 15:54:34   来源:该用户太帅没有设置昵称   查看:41  讨论:0
一、为什么你要用Redux。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
Redux是Flux的一种实现,除了Redux之外,还有很多实现flux的框架:Reflux、Fluxible等。HDd易塔云建站-模板下载,web开发资源,技术博客
Redux的出现是为了解决Flux的不足:Store之间依赖关系的不明确。Store混杂着逻辑和数据状态。开发者翻译Redux = Reducer + Flux。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
二、Redux的基本原则。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
    □:唯一数据源(只有一个store);HDd易塔云建站-模板下载,web开发资源,技术博客
    □:保持store的状态只读(只能通过dispacth派发action的行为,修改数据状态);HDd易塔云建站-模板下载,web开发资源,技术博客
    □:数据改变用纯函数Reducer(in Redux,每个reducer的函数签名为:reducer(state, action))。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
三、Redux流程图(网摘+改进)。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
1、唯一数据源:整个应用的state都被储存到一个状态树里,并且这个状态树,只存在于唯一的store中。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
2、保持只读状态:state是只读的,唯一改变state的方法就是触发action,action是一个动作。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
3、数据改变通过纯函数:用reducer,纯函数,改变数据。
HDd易塔云建站-模板下载,web开发资源,技术博客
四、Redux概念解析。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
1、Store。
HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
就是保存数据的地方,你可以把它看成一个数据,整个应用只能由一个store。Redux提供creatorStore函数,来生成store。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
2、State。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
state就是store里面存储的数据,store里面可以拥有多个state,Redux规定一个state对应一个View,只要state相同,view就是一样的。反过来也一样,可以通过store.getState()获取。
import {createStore} from 'redux'
const store=createStore(fn);
const state=store.getState()
HDd易塔云建站-模板下载,web开发资源,技术博客
3、Action。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
state的改变会导致view的变化,但是在redux中不能直接操作state,也就是说不能使用this.setState来操作,用户只能接触到view。在Redux中提供了一个对象来告诉Store需要改变state。Action是一个对象其中type属性是必须的,表示Action的名称,其他的可以根据需求自由设置。
const action={
  type:'ADD_TODO',
  payload:'redux原理'
}
在上面的代码中,Action的名称是ADD_TODO,携带的数据是字符串'redux原理',Action描述当前发生的事情,这是改变state的唯一方式。(如果当前类型是,那么加载xxx)HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
4、store.dispatch()。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
store.dispacth()是view发送action的唯一办法。
store.dispatch({
  type:'ADD_TODO',
  payload:'redux原理'
})
store.dispatch()接收一个action作为参数,将它派发给store,通知它要更新state。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
5、Reducer。HDd易塔云建站-模板下载,web开发资源,技术博客
HDd易塔云建站-模板下载,web开发资源,技术博客
store收到Action以后,必须给出一个新state,这样view才会发生变化。这种state的计算过程就叫Reducer。HDd易塔云建站-模板下载,web开发资源,技术博客
reducer是一个纯函数,他接受 state(当前状态) 和 action(接收到的action对象)作为参数,返回一个新的state。
const reducer =(state,action)=>{
  switch(action.type){
    case ADD_TODO:
        return newstate;
    default return state
  }
}
HDd易塔云建站-模板下载,web开发资源,技术博客
五、Redux源码。
let createStore = (reducer) => {
    let state;
    //获取状态对象
    //存放所有的监听函数
    let listeners = [];
    let getState = () => state;
    //提供一个方法供外部调用派发action
    let dispath = (action) => {
        //调用管理员reducer得到新的state
        state = reducer(state, action);
        //执行所有的监听函数
        listeners.forEach((l) => l())
    }
    //订阅状态变化事件,当状态改变发生之后执行监听函数
    let subscribe = (listener) => {
        listeners.push(listener);
    }
    dispath();
    return {
        getState,
        dispath,
        subscribe
    }
}
let combineReducers=(renducers)=>{
    //传入一个renducers管理组,返回的是一个renducer
    return function(state={},action={}){
        let newState={};
        for(var attr in renducers){
            newState[attr]=renducers[attr](state[attr],action)

        }
        return newState;
    }
}
export {createStore,combineReducers};
六、Redux使用案例。HDd易塔云建站-模板下载,web开发资源,技术博客
html:
<div id="counter"></div>
  <button id="addBtn">+</button>
  <button id="minusBtn">-</button>
js代码:
function createStore(reducer) {
    var state;
    var listeners = [];
    var getState = () => state;
    var dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach(l=>l());
    }
    var subscribe = (listener) => {
        listeners.push(listener);
        return () => {
            listeners = listeners.filter((l) => l != listener)
        }
    }
    dispatch();
    return {
        getState, dispatch, subscribe
    }
}
var reducer = (state = 0, action) => {
    if (!action) return state;
    console.log(action);
    switch (action.type) {
        case 'INCREMENT':
            return state + 1;
        case 'DECREMENT':
            return state - 1;
        default:
            return state;
    }
}
var store = createStore(reducer);
store.subscribe(function () {
    document.querySelector('#counter').innerHTML = store.getState();
});

document.querySelector('#addBtn').addEventListener('click', function () {
    store.dispatch({type: 'INCREMENT'});
});
document.querySelector('#minusBtn').addEventListener('click', function () {
    store.dispatch({type: 'DECREMENT'});
});

评论

  • 匿名