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; //优化一下,判断一下当前状态值到底变了没有,不改变就返回老的。
  };
}
相关推荐
拾光拾趣录6 分钟前
闭包:从“变量怎么还没死”到写出真正健壮的模块
前端·javascript
拾光拾趣录27 分钟前
for..in 和 Object.keys 的区别:从“遍历对象属性的坑”说起
前端·javascript
OpenTiny社区38 分钟前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
编程猪猪侠1 小时前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞1 小时前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路2 小时前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失9492 小时前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue8682 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie2 小时前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_2 小时前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api