React状态管理库 -- Redux篇

如何实现一个redux?

确切来说应该是js状态管理库, redux现在常用redux-toolkit,以后有机会总结。

  1. 什么是reducer?

    reducer 是一个纯函数,传入旧的state和action,返回新的state。(可以类比js reduce函数)。

JavaScript 复制代码
   const reducer =  (previousState, action) => newState
  1. Redux基本概念
  • React Component
  • Action Creators
  • Store
  • Reducers
  1. Redux 基本使用
JavaScript 复制代码
export default function ReduxPage(){
    const [state, setState] = useState(store.getState().count);
    const add = () => {
        store.dispatch({type: 'ADD'})
    }
    const minus = () => {
        store.dispatch({type: 'Minus'})
    }
    useEffect(() => {
        const unsubscribe = store.subscribe(() => {
            setState(store.getState().count);
        });
        return () => unsubscribe();
    }, []);
    return(
        <div>
            <h3>ReduxPage</h3>
            <p>{state}</p>
            <button onClick={add}>add</button>
        </div>
    )
}
JavaScript 复制代码
function countReducer(state = 0, action){
    switch(action.type){
        case "ADD":
            return state + 1
        case "Minus":
            return state - 1
        default:
            return state
    }
}
export const store = createStore(countReducer)
  1. Redux基本实现

createStore -- 发布订阅模式

接收什么?

目前是一个reducer。(还可以加入中间件)

返回什么?

{getState,dispatch,subscribe}三个方法。

JavaScript 复制代码
export default function createStore (reducer) {
    let currentState
    let currentListeners = []
    function getState(){
        return currentState
    }
    function dispatch(action){
        currentState = reducer(currentState,action)
        currentListeners.forEach(listener=>{
            listener()
        })
    }
    function subscribe(listener){
        currentListeners.push(listener)
        return () => {
            const index = currentListeners.indexOf(listener)
            currentListeners.splice(index,1)
        }
    }
    dispatch({type:'ADADAD'})
    return {getState,dispatch,subscribe}
}

思考: 为什么要dispatch({type:'ADADAD'}),其实是拿到初始状态(本例子中的state = 0),触发default:return state不要忘记加

  1. rudux中间件 想要增强redux的功能,如异步(redux-thunk),日志打印(redux-logger)等,可以使用中间件来增强一般的redux,以后有机会总结一下如何实现。

  2. 管理多个reducer

在一个项目中,可能会有很多不同的状态需要管理,也就是有很多reducer, 那么我们需要将多个reducer合并成一个reducer。

怎么使用呢?

JavaScript 复制代码
export const store = createStore(
    combineReducers({count:countReducer,和其他reducer}),
    applyMiddleware(thunk,logger)) //这个是中间件,暂时可以不管它

如何实现一个combineReducer?

先考虑接受什么参数? -- 一个对象,包含所有reducer。

返回什么? 一个总的reducer。

JavaScript 复制代码
export default function combineReducers(reducers) {
  return function combination(state = {}, action) {
    let nextState = {};
    let hasChanged = false;

    for (let key in reducers) {
      const reducer = reducers[key];
      nextState[key] = reducer(state[key], action);
      hasChanged = hasChanged || nextState[key] !== state[key];
    }

    hasChanged =
      hasChanged || Object.keys(reducers).length !== Object.keys(state).length;

    return hasChanged ? nextState : state; //优化一下,判断一下当前状态值到底变了没有,不改变就返回老的。
  };
}
相关推荐
Captaincc1 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师3 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen3 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒3 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow4 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林8184 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang800784 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明4 小时前
第 6 章 组件进阶
前端·vue.js
江华森4 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端
南青4 小时前
Vue 3 中后台实战:我踩过的 10 个坑和最佳实践
前端