提供者和连接如何在反应中工作?



1-Provider

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

2-connect

如何将 redux 存储作为组件props传递connect

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

下面是一个完全工作的简单 React Redux 示例,它只显示 redux 存储中的一个名称并使用 React ReduxconnectProvider,那么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"));

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

为了能够理解Providerconnect是如何工作的,我们需要了解 React 中的 2 个概念

1-上下文API:

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

2- 高阶分量 (HOC):

高阶组件是一个函数,它接受一个组件并返回一个新组件,但在返回新组件之前,您可以传递额外的自定义 props 然后返回它,您可以在此处了解有关 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,
}

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

使用我们自己的MyProvidermyConnect的相同简单示例

//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"));

您可以在此处测试上述实现 https://codesandbox.io/s/727pl0mqoq


这个例子简单说明了如何利用 ReactContextHOC来构建 react-reduxProviderconnect

这让我们更好地理解为什么我们使用ProviderconnectmapStateToProps

最新更新