我很抱歉这个愚蠢的问题,我正在学习React,所以我根本不是专家。
我想知道是否有一种方法可以扩展我的无状态组件的某些功能,而不会总是创建包装器,它们将连接到Redux存储并通过props传递数据。
高阶组件是最好的方法吗?
让我用几行代码更好地解释一下。 下面的示例组件应该在用户单击事件上调用API /收藏夹(POST)以创建“收藏夹”实体,并且它将调用相同的API(DELETE)以便将其删除。
这是我意识到的解决方案:
const HOC_DISPLAY_NAME = 'HOCFavouriteIcon';
export default function HOCWrapperFavourite(FavouriteComponent) {
return class extends React.Component {
static displayName = HOC_DISPLAY_NAME;
constructor(props) {
super(props);
this.state = this.getDefaultState();
this.bindMethods();
}
getDefaultState() {
return {
isFavourite: false,
addFavouritePayload: null,
removeFavouritePayload: null,
};
}
render() {
return (
<DataProviderApiFavourites
create={this.state.addFavouritePayload}
createListener={this.favoriteCreateHandler}
delete={this.state.removeFavouritePayload}
deleteListener={this.favoriteDeleteHandler}
>
<FavouriteComponent
{...this.props}
{...this.state}
addFavourite={this.addFavouriteClickHandler}
removeFavourite={this.removeFavouriteClickHandler}
/>
</DataProviderApiFavourites>
);
}
addFavouriteClickHandler(visitorId, artId) {
this.setState({
addFavouritePayload: {visitorId, artId},
});
}
removeFavouriteClickHandler(visitorId, favouriteId) {
this.setState({
removeFavouritePayload: {visitorId, favouriteId},
});
}
favoriteCreateHandler(result){
// do something when a favorite entity was created
}
favoriteDeleteHandler(result){
// do something when a favorite entity was deleted
}
bindMethods() {
this.addFavouriteClickHandler = this.addFavouriteClickHandler.bind(this);
this.removeFavouriteClickHandler = this.removeFavouriteClickHandler.bind(this);
this.favoriteCreateHandler = this.favoriteCreateHandler.bind(this);
this.favoriteDeleteHandler = this.favoriteDeleteHandler.bind(this);
}
}
};
DataProviderApiFavourites有一个接受JSON有效负载的属性“create”,它将触发Saga捕获的Redux动作(谁将调用API),并且它还能够通过createListener函数通知结果。 删除支柱也是如此(但它会调用delete API并通过favoriteDeleteHandler进行通知)。
考虑到FavouriteComponent是一个无状态组件,为了使用UI组件中数据组件的功能,它是一个很好的结构吗?
实际上,可以在不嵌套子组件的情况下使用DataProviderApiFavourites,它返回null或者如果设置了this.props.children。
如果有人帮我理解我是否会做错事,我真的很感激。
答案 0 :(得分:1)
当然,HOC完全适合此用例。
代码很好,但是要坚持组合和可重用性的概念,我将构建一个更通用的HOC,并且不要在其中添加太多逻辑,然后如果您需要更具体的内容,请传递参数或在其之上构建另一个HOC。
例如:
const HOC = store => WrappedComponent => props => (
// Render your wrapped component, spread the store to his props
);
要将商店作为参数传递给HOC的地方,然后,如果需要其中的特定切片,可以将其指定为第一个参数,或者使用另一个HOC抽象。
简而言之,不要使用将直接接受包装的组件的HOC,而是将另一个HOC接受第一个参数,这将为您提供更大的灵活性。第一个参数可以是redux存储,解构的redux存储,默认状态等,具体取决于您选择使用的逻辑。