【问题标题】:React Higher Order Component Initial PropsReact 高阶组件初始道具
【发布时间】:2016-11-16 17:20:06
【问题描述】:

我正在创建一个播放器库,并希望 React 流程如下所示:

PlayerHOC -> PlaylistHOC -> FooterContainer。

我希望它朝这个方向发展的原因是 PlayerHOC 具有 PlaylistHOC 和 FooterContainer 需要访问的方法(即从道具)。

我的代码:

class FooterContainer extends React.Component {
    render() {
        return (
            <div>
                <div className="jp-type-footer" >
                    //...
                </div>
            </div>
        );
    }
}

class FooterPlayer extends React.Component {
    constructor() {
        super();

        this.options = {
            smoothPlayBar: false,
            muted: true,
            //...
        };
    }
    render() {
        return (
            <Player {...this.options} />
        );
    }
};

export const PlaylistHOC = (WrappedComponent) => class extends React.Component {
    constructor(props) {
        super(props);

        //Add a new stateClass for the extra loop option
        this.stateClass = merge({
            shuffled: "state-shuffled", 
            loopedPlaylist: "state-loop-playlist"
        }, this.props.stateClass);   
    }
    setPlaylist = () => {}
};

export const PlayerHOC = (WrappedComponent) => class extends React.Component {
    constructor(props) {
        super(props);

        //get passed in props from FooterPlayer and PlaylistHoc
    }
    play = () => {}
    pause = () => {}
};

const Player = PlayerHOC(PlaylistHOC(FooterContainer));

export default connect()(FooterPlayer);

我还将道具从FooterPlayer 传递到PlayerHOC,效果很好。但是,我还想将永远不会更新的默认道具从 PlaylistHOC 传递到 PlayerHOC,我不知道如何在保持这种流动的同时做到这一点。

例如:const Player = PlaylistHOC(PlayerHOC(FooterContainer)); 这将允许我将初始道具从PlaylistHOC 和FooterPlayer 传递给PlayerHOC,但是我将无法通过道具访问PlayerHOC 方法。

我该怎么做?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    我会使用const Player = PlaylistHOC(PlayerHOC(FooterContainer));,因为父组件无法从其子组件接收道具。

    看起来PlaylistHOC 和PlayerHOC 都是mixin,所以它们应该从被包装的组件继承而不是React.Component。

    我稍微更改了代码以便能够对其进行测试,但它的关键思想是我如何在你的 mixins 中扩展 WrappedComponent 而不是 React.Component。

    class FooterContainer extends React.Component {
        render() {
            return (
                <div>
                    <div className="jp-type-footer">
                        <button onClick={this.play.bind(this)}>Play</button>
                    </div>
                </div>
            );
        }
    }
    
    class FooterPlayer extends React.Component {
        constructor() {
            super();
    
            this.options = {
                smoothPlayBar: false,
                muted: true
                //...
            };
        }
        render() {
            return (
                <Player {...this.options} />
            );
        }
    };
    
    export const PlaylistHOC = (WrappedComponent) => class extends WrappedComponent {
        constructor(props) {
            super(props);
    
            //Add a new stateClass for the extra loop option
            //this.stateClass = merge({
            //      shuffled: "state-shuffled",
            //    loopedPlaylist: "state-loop-playlist"
            //}, this.props.stateClass);
        }
        setPlaylist() {
    
        }
    };
    
    export const PlayerHOC = (WrappedComponent) => class extends WrappedComponent {
        constructor(props) {
            super(props);
    
            //get passed in props from FooterPlayer and PlaylistHoc
        }
        play() {
          console.log('playing');
        }
        pause() {
    
        }
    };
    
    const Player = PlaylistHOC(PlayerHOC(FooterContainer));
    
    export default connect()(FooterPlayer);
    

    顺便说一句,试试decorators 一些非常花哨的语法,比如

    @PlayerlistHOC
    @PlayerHOC
    class FooterContainer {
    
    }
    

    请注意,装饰器不是确定性的,可能会发生很大变化。

    【讨论】:

    • 好主意,但两种方法都返回未定义。 WrappedComponent() 也会引发错误。所以我不认为我可以这样做。
    • 我刚刚意识到WrappedComponent 是对类的引用,而不是它的实例,并且由于它依赖于原型继承,因此prototype 上的方法应该可用。试试新代码
    • 这也不起作用,似乎只是使用 Refs 的一种骇人听闻的方式,我试图避免这种方式
    • 终于有时间好好试一试了,希望这次能有所帮助:)
    • 这行得通,非常感谢。我刚刚发现这是Inheritance Inversion。 React 说我们应该更喜欢组合而不是inheritance。我应该只使用 refs + composition 吗?或者这对 HOC 没问题?
    猜你喜欢
    • 1970-01-01
    • 2018-04-03
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 2021-04-14
    • 2019-10-31
    • 2017-12-03
    相关资源
    最近更新 更多