Provider和connect如何做出反应?

Amr*_*bib 18 javascript reactjs redux react-redux

1- Provider

为什么我们需要将所有组件包装在里面Provider

2- connect:

如何connect通过redux存储props组件?

3-我们可以建立我们自己的Providerconnect

下面是刚刚从Redux的商店显示的名称,并使用阵营终极版全工作简单阵营终极版例子connectProvider,所以怎么ConnectedComponent能简单地访问this.props.name

import React, { Component } from "react";
import { render } from "react-dom";
import { createStore } from "redux";
import { Provider, connect } from "react-redux";

var defaultState = {
  name: "Amr"
};

function rootReducer(state = defaultState, action) {
  return state;
}

var store = createStore(rootReducer);


class ConnectedComp extends Component {
  render() {
    return (
        <h2>{this.props.name}</h2>
    );
  }
}
function mapStateToProps(state) {
  return {
    name: state.name
  };
}
ConnectedComp = connect(mapStateToProps)(ConnectedComp);



class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <ConnectedComp />
      </Provider>
    );
  }
}

render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)

这是一个完整的工作示例https://codesandbox.io/s/lpvnxro7n7

Amr*_*bib 27

为了能够理解我们在React中理解2个概念的方法Providerconnect工作

1-上下文api:

上下文是一种通过组件树传递数据而不必在每个级别手动传递道具的方法,您可以在此处了解有关上下文的更多信息

2-高阶分量(HOC):

高阶组件是一个获取组件并返回新组件的函数,但在返回新组件之前,您可以传递额外的自定义道具,然后将其返回,您可以在此处了解有关HOC的更多信息


3-建立自己的Providerconnect

现在,我们理解这两种语境和高阶组件,我们将用它们来创建这个问题同样完全工作的例子,但用我们自己的建造myProvidermyConnect


MyProvider

//This is how we utilize React Context and create MyProvider component that will pass store to all its child components automatically
//This is also known by Provider pattern
class MyProvider extends Component {
  //By adding the getChildContext function and childContextTypes, React passes the information down automatically to any component in the subtree
  getChildContext() {
    const { store } = this.props
    return { store }
  }

  render() {
    return this.props.children;
  }
}

MyProvider.childContextTypes = {
  store: PropTypes.object.isRequired,
}
Run Code Online (Sandbox Code Playgroud)

myConnect

//This is the Higher Order Component
function myConnect(mapStateToPropsFunc) {
  return function (WrappedComp) {
    var myHOC = class HOC extends Component {
      render() {
        //Now we access redux store using react context api as it will be passed by MyProvider automatically to all child components
        var myStore = this.context.store.getState();
        //mapStateToPropsFunc is just used to structure the props required by the component so we pass to mapStateToPropsFunc the whole store and then it returns a mapped object with required props thats why it is well known by mapStateToProps
        var storeToBePassed = mapStateToPropsFunc(myStore);
        return (
          //We pass the result from executing mapStateToPropsFunc to the wrapped component and this is how the components get passed props from redux store
          <WrappedComp {...storeToBePassed} />
        )
      }
    }

    //We need to define contextTypes otherwise context will be empty
    myHOC.contextTypes = {
      store: PropTypes.object
    };

    //return new component that has access to redux store as props mapped using mapStateToProps function
    return myHOC;
  }
}
Run Code Online (Sandbox Code Playgroud)

使用我们自己MyProvider和的相同的简单示例myConnect

//Note that we removed react-redux library
import React, { Component, Children } from "react";
import { PropTypes } from "prop-types";
import { render } from "react-dom";
import { createStore } from "redux";

var defaultState = {
  name: "Amr"
};

function rootReducer(state = defaultState, action) {
  return state;
}

var store = createStore(rootReducer);

class App extends Component {
  render() {
    //Here we use our own built myProvider and pass store
    return (
      <MyProvider store={store}>
        <ConnectedComp />
      </MyProvider>
    );
  }
}

class ConnectedComp extends Component {
  render() {
    return (
      <h2>{this.props.name}</h2>
    );
  }
}

//mapStateToProps is a normal function that get store as parameter and return the required props by that component, btw this function can have any name
function mapStateToProps(state) {
  return {
    name: state.name
  };
}

//Here we use our own built myConnect
ConnectedComp = myConnect(mapStateToProps)(ConnectedComp);

render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)

你可以在这里测试上面的实现https://codesandbox.io/s/727pl0mqoq


这个例子是如何反应-Redux的一个简单的例子Provider,并connect可以通过利用两个阵营构建ContextHOC.

这使我们更好地理解我们使用的原因Provider,connect并且mapStateToProps