React-redux has the following functions:

  1. Provider provides stores for descendant components
  2. Connect provides data and change methods for components
  3. Automatically updates components as data changes

To see what react-Redux does, go here

Let’s start implementing some of the features of React-Redux:

//my-react-redux.js
import React, {useContext, useReducer, useLayoutEffect} from "react";
const Context = React.createContext(); // Create global state

//1. Implement the Provider component: Provide stores for future components
export function Provider({store, children}) {
  return <Context.Provider value={store}>{children}</Context.Provider>;
}

//2. Implement connect methods: Provide data and change methods for components
export const connect = (
mapStateToProps = state => state,     // The default is a method
mapDispatchToProps
) = > WrappendComponent= > props= > {  // WrappendComponent is the benefit component
  const store = useContext(Context)
  const {dispatch, getState, subscribe} = store
  const stateProps = mapStateToProps(getState()) // Get the required state
  let dispatchProps = { dispatch }
  // a method to force a function to update
  const [ignored, forceUpdate] = useReducer(x= > x + 1.0);
  //mapDispatchToProps can be function or object
  if (typeof mapDispatchToProps === "function") {
     dispatchProps = mapDispatchToProps(dispatch)
  } else if (typeof mapDispatchToProps === "object") {
     dispatchProps = bindActionCreators(mapDispatchToProps, dispatch)
  }
  //3. Implement automatic updating of components when side effect state changes
  useLayoutEffect(() = > {
    // Subscribe to state changes
    const unsubscribe = subscribe(() = > {
       forceUpdate() // Force refresh
    })
    // Returns an unsubscribe function
    return () = > {
     if (unsubscribe) {
       unsubscribe()
     }
    }
  }, [store])
  // Map state and Dispatch to the component to complete the connect task
  return <WrappendComponent {. props} {. stateProps} {. dispatchProps} / >
}

function bindActionCreator(creator, dispatch) {
  return (. args) = >dispatch(creator(... args)) }// A bindActionCreators method is required in the @connect() decorator
// The function is to structure creators. Simply write Type to implement the dispatch method automatically, making creators writing easier
function bindActionCreators(creators, dispatch) {
  const obj = {};
  for (let key in creators) {
    obj[key] = bindActionCreator(creators[key], dispatch)
  }
  return obj
}
Copy the code

Learn about the @Connect () decorator here

Implement the Hooks API:

  1. UseSelector gets the store state
  2. UseDispatch for dispatch
export function useSelector(selector) {
  const store = useStore()
  const {getState, subscribe} = store
  const selectedState = selector(getState())
  const [ignored, forceUpdate] = useReducer(x= > x + 1.0);
  useLayoutEffect(() = > {
    const unsubscribe = subscribe(() = > {
     forceUpdate()
    });
    return () = > {
     if (unsubscribe) {
       unsubscribe()
     }
   };
  }, [store])
  return selectedState
}
export function useDispatch() {
  const store = useStore()
  return store.dispatch
}
export function useStore() {
  const store = useContext(Context)
  return store
}
Copy the code

Use:

import React, {useCallback} from "react"
import {useSelector, useDispatch} from "react-redux"
export default function ReactReduxHookPage({value}) {
  const dispatch = useDispatch()
  const add = useCallback(() = > {
    dispatch({type: "ADD"}}), [])const count = useSelector(({count}) = > count);
  return (
    <div>
      <h3>{count}</h3>
      <button onClick={add}>add</button>
   </div>)}Copy the code