手撸一套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