Let’s implement our own React-redux today. React Context API: Redux redux redux redux redux redux redux redux redux redux redux redux redux redux redux redux

Start with the import file

First we need to make the following changes in the entry file index.js file, to introduce our own file, at this time because we have not created the file, naturally error, do not worry about proceed

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from '@/pages/home'
// Introduce our own provider
import { Provider } from './myReactRedux/provider'
// Import the previous store
import store from '@/store/store'
ReactDOM.render(
  <React.StrictMode>
    <Provider store={ store} >
      <App />
    </Provider>
  </React.StrictMode>.document.getElementById('root'));Copy the code

Create myReactRedux folder

Let’s create myReactRedux under SRC, Create bindActionCreators.js connect.js createcontext.js provider.js, and we’ll start with the simplest provider

import React, { Component } from 'react'
// Provider is simply a higher-order component
class Provider extends Component {
    render() {
        return (
            <div>
                {this.props.children}
            </div>)}}export { Provider }
Copy the code

Now that we have page content, how do we pass our store data?

Create createcontext.js content

Here we need to use the REACT API context to pass data down

The createcontext.js code is relatively simple and I posted it as the original React API

import React from 'react'
// react context
const ValueContext = React.createContext();
export default ValueContext
Copy the code

At this point we come back to binding store to provider.js

import React, { Component } from 'react'
/ / introduction
import ValueContext from './createContext'
class Provider extends Component {
    render() {
        return (
            // The context property is passed, where the data subscribed to the store is passed to the component
            <ValueContext.Provider value={ this.props.store} >
                {this.props.children}
            </ValueContext.Provider>)}}export { Provider }
Copy the code

At this point we can print this. Props on the console.

Create connect.js content

To analyze the structure, connect is a function that takes two parameters and passes them to the component. The code looks like this

import React, { Component } from 'react'
// Receive parameters, components, directly return components
export const connect = (mapStateToProps, mapDispatchToProps) = > WrappedComponent= > { 
    return class extends Component {         
        render() {
            return <WrappedComponent />; }}}Copy the code

The connect function subscription data is passed to the component

Our store data is passed down using contect. We first import the created context to get the context, and store data

import React, { Component } from 'react'
import ValueContext from './createContext'
// Receive parameters and components and return components directly
export const connect = (mapStateToProps, mapDispatchToProps) = > WrappedComponent= > { 
    return class extends Component { 
        // Mounts the contextType attribute
        static contextType = ValueContext
        
        render() {

            return <WrappedComponent />; }}}Copy the code

Now the context is going to be mounted on this

Six, mapStateToProps

The state is on the mapStateToProps that we passed in, which is a function, so we’re just going to return it, we’re going to process the data in the mount phase, and we’re just going to pass the value to the component

import React, { Component } from 'react'
import ValueContext from './createContext'
// Receive parameters and components and return components directly
export const connect = (mapStateToProps, mapDispatchToProps) = > WrappedComponent= > { 
    return class extends Component { 
        // Mounts the contextType attribute
        static contextType = ValueContext
        // In order to change the props to make the component change, you need to call setState
        constructor(props) {
            super(props);
            this.state = {
                props: {}}; }componentDidMount() { 
            this.update();
            // We get the value of the context in the mount phase
            const { subscribe, getState } = this.context
            subscribe(() = > { 
                this.update();
            })
        }
        update = () = > { 
            const { getState, dispatch } = this.context;
            // Check the type passed in
            // console.log(mapStateToProps, mapDispatchToProps);
            // Return the value of state directly
            const stateProps = mapStateToProps(getState())
            
            let dispatchProps;
            
            this.setState({
                props: {... stateProps, ... dispatchProps } }); }render() {

            return <WrappedComponent {. this.props} {. this.state.props} / >; }}}Copy the code

Seven, mapDispatchToProps

We know that the mapDispatchToProps can accept an object or a function, but the function needs to use the bindActionCreators bound dispatch, so we need to deal with both of them separately. We’ll start with the bindActionCreators function

function bindActionCreator(creator, dispatch) {
    return (. args) = >dispatch(creator(... args)); }// Loop bind package dispatch
function bindActionCreators(creators,dispatch) {
    const obj = {};
    for (const key in creators) {
        obj[key] = bindActionCreator(creators[key],dispatch);
    }
    return obj;
}
export { bindActionCreators }
Copy the code

And then we can implement our mapDispatchToPropsle

import React, { Component } from 'react'
import ValueContext from './createContext'
import { bindActionCreators } from './bindActionCreators'
// Receive parameters and components and return components directly
export const connect = (mapStateToProps, mapDispatchToProps) = > WrappedComponent= > { 
    return class extends Component { 
        // Mounts the contextType attribute
        static contextType = ValueContext
        constructor(props) {
            super(props);
            this.state = {
                props: {}}; }componentDidMount() { 
            this.update();
            // We get the value of the context in the mount phase
            // What's in context
            // console.log(this.context)
            const { subscribe, getState } = this.context
            // We can already see our values here
            // console.log(getState())
            subscribe(() = > { 
                this.update();
            })
        }
        update = () = > { 
            const { getState, dispatch } = this.context;
            // Check the type passed in
            // console.log(mapStateToProps, mapDispatchToProps);
            // Return the value of state directly
            const stateProps = mapStateToProps(getState())
            
            let dispatchProps;
            if (typeof mapDispatchToProps === "object") {
                // Add dispath to object
                dispatchProps = bindActionCreators(mapDispatchToProps,dispatch);
            } else if (typeof mapDispatchToProps === "function") {
                // Bind the dispath method
                dispatchProps = mapDispatchToProps(dispatch, this.props);
            } else {
                // Direct binding
                dispatchProps = { dispatch };
            }
            this.setState({
                props: {... stateProps, ... dispatchProps } }); }render() {

            return <WrappedComponent {. this.props} {. this.state.props} / >; }}}Copy the code

Ok, did you get it? Come and try new skills!