我想创建一个像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中实现这一目标?
答案 0 :(得分:1)
如果您正在使用Redux
,最好将响应对象存储在商店中并通过连接的组件访问它。其余的答案是如何做到但不建议。在context
方法中,您需要确保在呈现应用程序之前完成req / res,这意味着在您收到响应后调用ReactDOM.render
。
您可以使用<SearchContextProvider />
组件来实现此目的,该组件将使用React context。然后使用HOC返回知道上下文的组件。包装应用程序后实例化提供程序并将响应对象作为prop传递。以下是一个高级别的解决方案。
class SearchContextProvider extends React.Component {
static childContextTypes = {
search: PropTypes.object
};
getChildContext() {
return { search: this.props.search };
}
render() {
return this.props.children; // React16
}
}
<SearchContextProvider search={data}>
<App />
</SearchContextProvider>
export function withSearchContext(ComponentToWrap) {
return class extends React.Component {
static contextTypes = {
search: PropTypes.object
};
render() {
return (
<ComponentToWrap
{...this.props}
search={this.context.search}
/>
);
}
};
}