想象一下,我有一些“页面”组件,需要从服务器请求数据。它请求的数据取决于当前用户是否经过身份验证。此外,在登录的情况下,页面将要重新加载数据。我的问题是,如何使用HOC而不是继承来完成这样的事情呢?
为了说明问题,我将演示使用继承的解决方案。该程序将具有以下对象。我将省略样板代码。
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()
中的更改。
答案 0 :(得分:1)
使用HOC时,不应将<button id="btn">Hide</button>
<p id="para">A dpara.</p>
函数放在包装组件上。而是将函数作为参数传递给HOC构造函数。
这样的事可能适合你。 loadData
函数采用回调函数,每次会话状态更改时都会调用该函数。其结果将作为sessionHoc
道具传递给WrappedComponent
。
data
希望这有帮助! :)