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; //优化一下,判断一下当前状态值到底变了没有,不改变就返回老的。
  };
}
相关推荐
爱喝白开水a1 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
董世昌411 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
吃杠碰小鸡2 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone2 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09012 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农3 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king3 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
夏幻灵4 小时前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_4 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝4 小时前
RBAC前端架构-01:项目初始化
前端·架构