3

对于这个愚蠢的问题,我很抱歉,我正在学习 React,所以我根本不是专家。

我想知道是否有一种方法可以使用某些功能扩展我的无状态组件,而无需始终围绕它们创建包装器,它们将连接到 Redux 存储并通过道具传递数据。

高阶组件是最好的方法吗?

让我用几行代码更好地解释一下。下面的示例组件应在用户单击事件上调用 API /favourites (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 有一个属性“create”,它接受 JSON 有效负载,它将触发 Saga 捕获的 Redux 操作(谁将调用 API),它还能够通过 createListener 函数通知结果。它与 delete 属性相同(但它会调用 delete API 并通过 favoriteDeleteHandler 通知)。

考虑到 FavouriteComponent 是一个无状态组件,为了在 UI 组件中使用数据组件的功能,它是否是一个好的结构?

实际上,DataProviderApiFavourites 可以在不嵌套子组件的情况下使用,它返回 null 或 this.props.children 如果设置。

如果有人能帮助我了解我是否会做错事,我将不胜感激。

4

1 回答 1

1

当然,HOC 非常适合这个用例。

代码很好,但是,为了坚持组合和可重用性的想法,我会构建一个更通用的 HOC 并且不会在其中添加太多逻辑,然后如果您需要更具体的东西,请传递参数或构建另一个HOC 在它之上。

前任:

const HOC = store => WrappedComponent => props => (
    // Render your wrapped component, spread the store to his props
);

您可以将 store 作为参数传递给 HOC,然后如果您需要它的特定部分,请将其指定为第一个参数或使用另一个 HOC 抽象。

简而言之,与其使用直接接受包装组件的 HOC,不如制作另一个接受第一个参数的 HOC,它会给你更多的灵活性。第一个参数可以是 redux 存储、解构的 redux 存储、默认状态等,具体取决于您选择使用的逻辑。

于 2018-07-04T05:48:53.180 回答