学习了一下写代码像蔡徐抻大神的“Redux/react-redux/redux中间件设计实现剖析”,参考链接为https://juejin.cn/post/684490...,非常感谢这位大佬的知识分享,哈哈~
在使用react 17实现react-redux时发现会报错,便对代码进行了修改,并用react hook的方式实现,整体结构图如下(使用create-react-app新建项目):
react版本:
App.js:
import React from "react";
import { connect } from "./react-redux";
const addCountAction = {
type: "plus"
}
const subtractAction = {
type: "subtract"
}
const mapStateToProps = state => {
return {
count: state.count,
}
}
const mapDispatchToProps = dispatch => {
return {
addCount: () => {
dispatch(addCountAction)
},
subtractCount: () => {
dispatch(subtractAction)
}
}
}
function App(props) {
const { count, addCount, subtractCount } = props;
return (
<div className="app">
{count}
<button onClick={addCount}>增加</button>
<button onClick={subtractCount}>减少</button>
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
context.js:
import React from "react";
const MyContext = React.createContext();
export default MyContext;
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { createStore } from "./store";
import { reducer } from "./reducer";
import MyContext from "./context";
ReactDOM.render(
<MyContext.Provider value={{ store: createStore(reducer) }}>
<App />
</MyContext.Provider>,
document.getElementById('root')
);
react-redux.js:
import React, { useContext, useEffect, useState } from "react";
import MyContext from "./context";
export function connect(mapStateToProps, mapDispatchToProps) {
return function (Component) {
function Connect(props) {
const context = useContext(MyContext);
const [count, setCount] = useState(0);//强制代码更新
useEffect(() => {
context.store.subscribe(handleStoreChange);
}, [context.store])
const handleStoreChange = () => {
setCount(count => count + 1)
}
return (
<Component
{...props}
{...mapStateToProps(context.store.getState())}
{...mapDispatchToProps((context.store.dispatch))}
/>
)
}
return Connect
}
}
reducer.js:
const initialState = {
count: 0
}
export function reducer(state = initialState, action) {
switch (action.type) {
case "plus":
return {
...state,
count: state.count + 1,
};
case "subtract":
return {
...state,
count: state.count - 1,
};
default:
return initialState
}
}
store.js:
export const createStore = (reducer) => {
let currentState = {};
let observers = [];
function getState() {
return currentState;
}
function dispatch(action) {
currentState = reducer(currentState, action);
observers.forEach(fn => fn());
}
function subscribe(fn) {
observers.push(fn);
}
dispatch({ type: "@@REDUX_INIT" });
return { getState, subscribe, dispatch }
}
最终效果:
代码已经上传到github上,有需要的自取https://github.com/chencaize/...
作者:点墨
版权:本文版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任