创建一个从服务器提供上下文数据的 React HOC
Create a React HOC that provides context data from server
我想创建一个类似于 react-router 的 HOC,为组件提供一些上下文相关的数据。需要从服务器获取上下文数据。
import React, { Component } from "react";
export function withSearchContext(ComponentToWrap) {
return class extends Component {
//should actually come from server
state = {
searchContext: {
key: "adedd34ddDdd1"
}
};
componentDidMount() {
this.getContextFromServer();
}
getContextFromServer() {
this.props.getContextFromServer().then(response => {
this.setState({searchContext: response.data});
});
}
render() {
return (
<ComponentToWrap {...this.props} searchContext={this.state.searchContext} />
);
}
};
}
我用起来像
import React, { Component } from 'react';
import { withSearchContext } from '../../Context';
@withSearchContext
class AccountDetail extends Component<{}, {}> {
componentDidMount = () => {
console.log(this.props.searchContext);
};
render() {
if(this.props.searchContext.key){
return (
<div className="detail-view flex-container">
{this.props.searchContext.key}
</div>
}
return <div> Loading ... </div>;
);
}
}
问题是我用它包装的每个组件都会调用 HOC。因此,对服务器的调用会发生多次。但是,我只需要 HOC 一次 运行 并为使用 HOC 的任何组件提供上下文。这在 React 中如何实现?
如果您使用 Redux
,最好将响应对象存储在存储中并通过连接的组件访问它。其余的答案是如何完成,但不建议这样做。在 context
方法中,您需要确保 req/res 在呈现应用程序之前完成,这意味着在收到响应后调用 ReactDOM.render
。
您可以使用将利用 React context 的 <SearchContextProvider />
组件来实现此目的。然后使用 HOC 到 return 感知上下文的组件。包装您的应用程序后实例化提供者并将响应对象作为道具传递。以下是高级解决方案。
SearchContextProvider.js
class SearchContextProvider extends React.Component {
static childContextTypes = {
search: PropTypes.object
};
getChildContext() {
return { search: this.props.search };
}
render() {
return this.props.children; // React16
}
}
App.js
<SearchContextProvider search={data}>
<App />
</SearchContextProvider>
withSearchContext.js
export function withSearchContext(ComponentToWrap) {
return class extends React.Component {
static contextTypes = {
search: PropTypes.object
};
render() {
return (
<ComponentToWrap
{...this.props}
search={this.context.search}
/>
);
}
};
}
我想创建一个类似于 react-router 的 HOC,为组件提供一些上下文相关的数据。需要从服务器获取上下文数据。
import React, { Component } from "react";
export function withSearchContext(ComponentToWrap) {
return class extends Component {
//should actually come from server
state = {
searchContext: {
key: "adedd34ddDdd1"
}
};
componentDidMount() {
this.getContextFromServer();
}
getContextFromServer() {
this.props.getContextFromServer().then(response => {
this.setState({searchContext: response.data});
});
}
render() {
return (
<ComponentToWrap {...this.props} searchContext={this.state.searchContext} />
);
}
};
}
我用起来像
import React, { Component } from 'react';
import { withSearchContext } from '../../Context';
@withSearchContext
class AccountDetail extends Component<{}, {}> {
componentDidMount = () => {
console.log(this.props.searchContext);
};
render() {
if(this.props.searchContext.key){
return (
<div className="detail-view flex-container">
{this.props.searchContext.key}
</div>
}
return <div> Loading ... </div>;
);
}
}
问题是我用它包装的每个组件都会调用 HOC。因此,对服务器的调用会发生多次。但是,我只需要 HOC 一次 运行 并为使用 HOC 的任何组件提供上下文。这在 React 中如何实现?
如果您使用 Redux
,最好将响应对象存储在存储中并通过连接的组件访问它。其余的答案是如何完成,但不建议这样做。在 context
方法中,您需要确保 req/res 在呈现应用程序之前完成,这意味着在收到响应后调用 ReactDOM.render
。
您可以使用将利用 React context 的 <SearchContextProvider />
组件来实现此目的。然后使用 HOC 到 return 感知上下文的组件。包装您的应用程序后实例化提供者并将响应对象作为道具传递。以下是高级解决方案。
SearchContextProvider.js
class SearchContextProvider extends React.Component {
static childContextTypes = {
search: PropTypes.object
};
getChildContext() {
return { search: this.props.search };
}
render() {
return this.props.children; // React16
}
}
App.js
<SearchContextProvider search={data}>
<App />
</SearchContextProvider>
withSearchContext.js
export function withSearchContext(ComponentToWrap) {
return class extends React.Component {
static contextTypes = {
search: PropTypes.object
};
render() {
return (
<ComponentToWrap
{...this.props}
search={this.context.search}
/>
);
}
};
}