反应高阶组件初始道具

时间:2016-11-16 17:20:07

标签: javascript reactjs

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

PlayerHOC -> PlaylistHOC -> FooterContainer

我希望它朝这个方向发展的原因是PlayerHOC上有PlaylistHOCFooterContainer需要访问的方法(即来自道具)。

我的代码:

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));这样我就可以将PlaylistHOCFooterPlayer的初始道具传递给PlayerHOC,但之后我无法访问{{1}道具的方法。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

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

PlaylistHOCPlayerHOC看起来都是mixins,因此它们应该从被包装的组件继承而不是React.Component

我已经更改了一些代码以便能够对其进行测试,但关键的一点就是我在你的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 {

}

警告装饰者不是确定的,可能会发生很大的变化。