学习了一下写代码像蔡徐抻大神的“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/...

作者:点墨
版权:本文版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

03-05 15:19