【Redux】手撸一套redux和react-redux,深入学习(四)

本文介绍了如何手动实现redux和react-redux的基本功能,通过创建ContextProvider将store注入到React应用中,然后讲解了connect函数的工作原理,包括mapStateToProps和mapDispatchToProps的作用,用于将store的状态和dispatch方法绑定到组件props上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

手撸一套redux和react-redux


回顾

https://blog.csdn.net/tuzi007a/article/details/129648459

react-redux

之前的三篇,学习了redux的写法,对思想和原理也做了了解。本篇开始学习react-redux。用到的方法都是react里面的,我们就简单说下吧。

在redux中,我们创建了状态仓库store。在react中,我们想要在全局能使用到store,就可以在根节点使用Context,把store作为value值传递下去。

import { createContext } from "react";

const ReduxContext = createContext();

const Provider = (props) => {

  const { store } = props;

  return <ReduxContext.Provider value={store}>
    { props.children }
  </ReduxContext.Provider>
}

export default Provider;
// src/index.js

import React, { StrictMode } from "react";
import { createRoot } from 'react-dom/client';
import App from './App';
import Provider from "./react-redux/Provider";
import { store } from "./redux/store";

const root = createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <StrictMode>
      <App />
    </StrictMode>
  </Provider>
)

按照Context的用法,我们只要想使用store,就需要先引入ReduxContext,用他来提取store。这很不方便。这时候就要思考,想要实现状态共享,我们应该怎么做?一般来说,有三种方式,

  • render props
  • 高阶组件
  • hook
    通过状态共享,让组件拿到想要的状态。
import { useContext, useEffect, useState } from "react";
// 这里引入打乱了 理解意思即可 
import { ReduxContext } from "./createReduxContext";

export const connect = (mapStateToProps, mapDispatchToProps) => {
  return function (Component) {
    return function Connect(props) {

      const ctx = useContext(ReduxContext);
      // console.log('ctx: ', ctx);

      const [states, setStates] = useState(ctx.getState());

      const mapDispatchToPropsWrap = dispatch => {
        const addDispatchToAction = {};
        for (let k in mapDispatchToProps) {
          addDispatchToAction[k] = () => dispatch(mapDispatchToProps[k]())
        }

        return addDispatchToAction;
      };

      useEffect(() => { 
        const unsub = ctx.subscribe(() => {
          setStates(ctx.getState());
        })

        return () => {
          unsub();
        }
      }, [ctx])

      return <Component
        {...props}
        {...mapStateToProps(states)}
        {...mapDispatchToPropsWrap(ctx.dispatch)}
      />
    }
  }
}

我们主要来说说mapStateToProps, mapDispatchToProps
这两个方法是要把状态和dispatch(action)以props的形式传给目标组件。
在应用时,connect中传入的状态和方法一般是这样写

connect(
	state => ({ count: state.count }),
	{ xxxaction }
)(App)

在connect源码中,mapStateToProps对应的就是state => ({ count: state.count }),这个方法的参数是state,最后返回一个状态对象,所以这个比较简单,我们只需要把store的最新状态传给mapStateToProps,然后把执行结果传给组件即可,组件就可以通过props来访问了。
mapDispatchToProps就稍微复杂一点。我们的action写法一般是个函数

// 同步的
const xxaction = data => ({ type: "xxx', data })

// 异步的
const xxaction = (params) => {
	dispatch => {
		// ...
		dispatch(action);
	}
}

在props拿到action之后,一般都会这么操作

const { xxaction } = props;

xxaction(data)
// 或者
xxaction(params)

也就是说,我们通过mapDispatchToProps传给props的action一定是这种形式

{
	xxaction: (xxx) => {
		dispatch(action(xxx))
	}
}

代码分享

https://gitee.com/guozia007/create-redux
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值