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; //优化一下,判断一下当前状态值到底变了没有,不改变就返回老的。
  };
}
相关推荐
Cobyte16 分钟前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT0629 分钟前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
剪刀石头布啊35 分钟前
生成随机数,Math.random的使用
前端
剪刀石头布啊35 分钟前
css外边距重叠问题
前端
剪刀石头布啊36 分钟前
chrome单页签内存分配上限问题,怎么解决
前端
剪刀石头布啊38 分钟前
css实现一个宽高固定百分比的布局的一个方式
前端
剪刀石头布啊42 分钟前
js数组之快速组、慢数组、密集数组、稀松数组
前端
mango_mangojuice1 小时前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
Days20501 小时前
简单处理接口返回400条数据本地数据分页加载
前端
Novlan12 小时前
@tdesign/uniapp 图标瘦身
前端