想象一下,我有一些“页面”组件,它需要从服务器请求数据。它请求的数据将取决于当前用户是否被认证。此外,如果登录,页面将要重新加载数据。我的问题是,我如何使用HOC而不是继承来完成像这样的事情?React Higher Order组件条件数据加载
为了说明这个问题,我将演示一个使用继承的解决方案。该计划将有以下对象。我会留下样板代码。
session
:一个EventEmitter
发射start
当会话改变(无论是一个登录或注销)。Page
:在所有页面从MyPage
继承父:的Page
在这个例子中,子类API
:将是一个API类从服务器
这里检索数据的代码:
// Page superclass
class Page extends React.Component {
componentWillMount() {
session.on("start", this.loadData);
this.loadData();
}
loadData() {
// this method is overwritten in subclasses
}
}
// MyPage subclass
class MyPage extends Page {
loadData() {
if(session.isAuthenticated()) {
API.loadPrivateData();
} else {
API.loadPublicData();
}
}
}
这是一个使用一个HOC一个解决方案,但似乎不是继承那么优雅。它仍然要求每个“子类”页面都有一个方法loadData
,它需要在每个“子类”componentWillMount
中调用该方法。
// Page HOC
function Page(WrappedComponent) {
return class EnhancedPage extends React.Component {
componentWillMount() {
session.on("start", this.loadData);
// this._page.loadData() will fail here
// since this._page is undefined until rendering finishes
}
loadData() {
this._page.loadData();
}
render() {
return <WrappedComponent {...props} ref={(e) => { this._page = e; }} />
}
}
}
// MyPage
class MyPage extends React.Component {
componentWillMount() {
this.loadData();
}
loadData() {
if(session.isAuthenticated()) {
API.loadPrivateData();
} else {
API.loadPublicData();
}
}
}
const component = Page(MyPage)
// what would make sense here is to have a method something like
// const component = Page(MyPage,() => MyPage.loadData())
// but then the MyPage.loadData logic would need to be defined
// elsewhere
这种模式将经常发生:我想加载一些数据,然后在会话更改时重新加载。我想了解完成相同的“反应”方式。
编辑:我不想通过HOC通过用户名或“loggedIn”标志。这就是说像<WrappedComponent isLoggedIn={session.isAuthenticated()} {...props} />
这样的东西不会在这里削减它。将API逻辑绑定到props
需要我检查MyPage.componentWillUpdate()
中的更改。
可能重复[反应:如何用HOC打包组件? (跨组件访问登录属性)](https://stackoverflow.com/questions/42372614/react-how-to-wrap-component-with-hoc-access-login-property-across-components) –
@NathanP。这是一个类似的问题,但我认为有一些重要的区别。 1)我没有使用REDX,这只是原始的反应。 2)我没有试图通过登录标志或用户名进行渲染,我试图在会话状态发生变化时执行一些特定于组件的操作。 – CaptainStiggz