控制反应组件渲染的顺序

Pos*_*Guy 9 javascript reactjs

如您所知,React组件并行渲染.无法保证他们完成渲染.

我想按照这个确切的顺序呈现以下组件:

  1. InterviewContentMain(因为它将呈现标题

    .我需要首先渲染此标题,以便在渲染后我可以在其他两个组件中对其进行操作.我将在其他两个组件的componentDidMount上运行一些JS,等等,这就是为什么我希望首先渲染它的原因)

  2. InterviewContainer(应该只在InterviewContentMain渲染后呈现)
  3. TableOfContents(应该只在InterviewContainer和InterviewContentMain渲染后呈现)

这是一个更多的上下文https://youtu.be/OrEq5X9O4bw

我尝试了一些东西,你可以看到生命周期方法,这可能是完全错误的,甚至不确定它是人们甚至在这种情况下做了什么,但到目前为止没有运气.

const Main = Component({
    getInitialState() {
        console.log("getInitialState being called");
        return null;
    },
    renderMe() {
        console.log("changed InterviewContent's state");
        this.setState({renderInk: true});
    },
    componentDidMount() {
        console.log("InterviewContentMain mounted");
    },
    render(){
        var company = this.props.company;

        return (
            <div id="ft-interview-content">
                <p className="section-heading bold font-22" id="interview-heading">Interview</p>
                <InterviewContent renderMe={this.renderMe} company={company}/>
            </div>
        )
    }
})

export default InterviewContentMain;


const InterviewContent = Component({
    componentDidMount() {
        console.log("InterviewContent mounted");
    },
    renderMe() {
        console.log("changed InterviewContent's state");
        this.setState({subParentRendered: true});
    },
    render(){
        var company = this.props.company;

        return (
            <div id="interview-content" className="clear-both">
                <div className="column-group">
                    <div className="all-20">
                        <TableOfContents renderHeader={this.props.renderMe}  renderContent={this.renderMe} company={company}/>
                    </div>
                    <div className="all-80">
                        <InterviewContainer company={company}/>
                    </div>
                </div>
            </div>
        )
    }
})

const TableOfContents = Component({
    enableInk() {
        new Ink.UI.Sticky(el, {topElement: "#interview-heading", bottomElement: "#footer"});
    },
    componentDidMount() {
        console.log("table of contents mounted");
        this.renderHeader;
        this.renderContent;
        enableInk(); // I only want to run this if the Header and the Content have rendered first
    },
    render(){
        return (
            <div>
                <p className="margin-8"><span className="blue medium"><Link to="/">HOME</Link></span></p>
        )
    }
})
Run Code Online (Sandbox Code Playgroud)

更新:

这是我试过的.虽然它们全部渲染,但我仍然得到TableOfContents在InterviewContentMain或InterviewContent之前呈现的时间,这意味着渲染重叠后的TableOfContent <p className="section-heading bold font-22" id="interview-heading">Interview</p>而不是渲染下面因为我试图在TableOfContents中应用的粘性JS

const InterviewContentMain = Component({
    getInitialState() {
        console.log("getInitialState being called");
        return {rendered: false};
    },
    componentDidMount() {
        console.log("InterviewContentMain mounted")
        this.setState({rendered: true});
    },
    render(){
        var company = this.props.company;

        return (
            <div id="ft-interview-content">
                <div className="section-heading bold font-22" id="interview-heading">Interview</div>
                { this.state.rendered && <InterviewContent company={company}/> }
            </div>
        )
    }
})

export default InterviewContentMain;


const InterviewContent = Component({
    getInitialState() {
        console.log("getInitialState being called");
        return {rendered: false};
    },
    componentDidMount() {
        console.log("InterviewContent mounted")
        this.setState({rendered: true});
    },
    render(){
        var company = this.props.company;

        return (
            <div id="interview-content" className="clear-both">
                <div className="column-group">
                    <div className="all-20">
                        <TableOfContents company={company}/>
                    </div>
                    <div className="all-80">
                        <InterviewContainer company={company}/>
                    </div>
                </div>
            </div>
        )
    }
})

const TableOfContents = Component({
    componentDidMount() {
        const el = ReactDOM.findDOMNode(this);
        new Ink.UI.Sticky(el,{topElement: "#interview-heading", bottomElement: "#footer"});
        console.log("TableOfContents mounted");
    },
    render(){
        return (
            <div>
                <p className="margin-8"><span className="blue medium"><Link to="/">HOME</Link></span></p>
            </div>
        )
    }
})
Run Code Online (Sandbox Code Playgroud)

azi*_*ium 4

如果您想有条件地渲染组件,请将其包装在条件中(无论是函数还是内联布尔表达式)

你说:

TableOfContents(仅应在 InterviewContainer 和 InterviewContentMain 呈现后呈现)

.. 因此,在父容器render的方法中TableOfContents,检查某些值是否为 true,就像在语句中一样if

render(){
    var company = this.props.company;

    return (
        <div id="interview-content" className="clear-both">
            <div className="column-group">
                <div className="all-20">
                  {this.state.subParentRendered &&
                    <TableOfContents renderHeader={this.props.renderMe}  renderContent={this.renderMe} company={company}/>
                  }
                </div>
                <div className="all-80">
                    <InterviewContainer company={company}/>
                </div>
            </div>
        </div>
    )
}
Run Code Online (Sandbox Code Playgroud)