In the react-Redux section, you need to subscribe to componentDidMount and unsubscribe when the component is destroyed. You also need to bind the Action with the boundActionCreators method. So how do you simplify these things? React-redux: redux: redux: Redux: Redux: Redux: Redux: Redux: Redux: Redux

Let’s start with the originalreact-reduxTo modify our component Counter1

  • The introduction ofProviderwillstorePass as an attributeProviderSo that theProviderAll the components of the package are availablestoreInstead of introducing a store in every component
import React from "react";
import ReactDOM from "react-dom";
+import { Provider } from "react-redux";
import store from "./store";

import Counter1 from "./components/Counter1";
import Counter2 from "./components/Counter2";

ReactDOM.render(
+  <Provider store={store}>
    <Counter1 />
    <Counter2 />
+  </Provider>.document.getElementById("root"));Copy the code
  • The introduction ofconnectMethod to bind the state in the store and the defined action to the component and inject it into the component props.
import React, { Component } from "react";
import actions from ".. /store/actions/counter1";
// Introduce the connect method
import { connect } from "react-redux";
class Counter1 extends Component {
  render() {
    // After connecting to the component, you can get properties in props
    let { number, add1, minus1 } = this.props;
    return (
      <div>
        <p>{number}</p>
        <button onClick={add1}>+</button>
        <button onClick={minus1}>-</button>
        <button onClick={()= >SetTimeout (() => add1(), 1000)}>1 second increment</button>
      </div>); }}let mapStateToProps = (state) = > state.counter1;
// Connect the component to the state and action
export default connect(mapStateToProps, actions)(Counter1);
Copy the code

Wouldn’t it be easier to have a store, bind actions, and define subscribing and unsubscribing functions in each component? How does that work internally?

implementationProvidercomponent

  • ProviderIs theReact contextA layer of encapsulation that provides store as value to all child components
import React from "react";
import ReactReduxContext from "./ReactReduxContext";

export default function (props) {
  return (
    <ReactReduxContext.Provider value={{ store: props.store}} >
      {props.children}
    </ReactReduxContext.Provider>
  );
}
Copy the code
  • createReactReduxContextobject
import React from "react";
export const ReactReduxContext = React.createContext(null);
export default ReactReduxContext;
Copy the code

Class component implementationconnectmethods

  • connectThe method is a higher-order function passed inmapStateToProps,actions, returns a higher-order component that encapsulates the original component and injects new properties and methods.
    • 1. First passcontextObtain the value provided by the Provider componentstore.
    • Retrieved in componentDidMountstoreSubscribe to the status of state, called when state changesforceUpdateMethod to re-render the component
    • 3, incomponentWillUnmountUnsubscribe when a component is about to uninstall
    • 4, inrenderGet in thestoreIn thestateAnd pass through the incomingmapStateToPropsMethod to get the state of a component dependencystatePropsAnd treat these states aspropsProperty injected intoOldComponentIn the component
    • 5, throughbindActionCreatorsMethod that will be passed inactionsandstoreIn thedispatchMethod to bind, the result of the binddispatchPropsAlso as apropsProperty injected intoOldComponentIn the component
  • So in theOldComponentIn can passpropsAttribute tostoreIn thestateAnd boundactionTo use
  • When callingactionLook tostoreEvent, passreducerFunction to update the state, which is then updated through component subscriptions
import React, { useContext } from "react";
import { bindActionCreators } from ".. /redux";
import ReactReduxContext from "./ReactReduxContext";

// Class component implementation
function connect(mapStateToProps, actions) {
  return function (OldComponent) {
    return class NewComponent extends React.Component {
      // Obtain the store provided by the Provider
      static contextType = ReactReduxContext;
      constructor(props, context) {
        super(props, context);
      }
      componentDidMount() {
      	// The subscription status changes and re-renders the component
        this.unsubscribe = this.context.store.subscribe(() = >
          this.forceUpdate()
        );
      }
      componentWillUnmount() {
        // Component unsubscribe
        this.unsubscribe();
      }
      render() {
      	// Get the state in store
        const { store } = this.context;
        const state = store.getState();
        // Get the status of component dependencies
        const stateProps = mapStateToProps(state);
        / / binding action
        const dispatchProps = bindActionCreators(actions, store.dispatch);
        return (
          <OldComponent {. this.props} {. stateProps} {. dispatchProps} / >); }}; }; }export default connect;
Copy the code

The code address

If this article is helpful to you, please give me a thumbs up