Provider和connect如何做出反应?

时间:2018-01-12 13:23:14

标签: javascript reactjs redux react-redux

1- Provider

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

2- connect

connect如何将redux存储为props到组件?

3-我们可以构建自己的Providerconnect吗?

下面是一个完全正常的简单React Redux示例,它只显示redux商店中的名称并使用React Redux connectProvider,因此ConnectedComponent只能访问{{1} }

this.props.name

这里有一个完整的例子https://codesandbox.io/s/lpvnxro7n7

1 个答案:

答案 0 :(得分:25)

为了能够了解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")); Provider如何运作,我们需要了解React中的2个概念

1- Context api:

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

2-高阶分量(HOC):

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

3-构建我们自己的connectProvider

现在我们理解了Context和Higher Order Component,我们将使用它们在问题中创建相同的完整工作示例,但使用我们自己构建的connectmyProvider

myConnect

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, }

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; } } MyProvider

的相同简单示例
myConnect

您可以在https://codesandbox.io/s/727pl0mqoq

测试上述实施

此示例简单说明了如何使用React //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")); Provider构建react-redux connectContext

这可让我们更好地了解我们使用HOCProviderconnect

的原因