首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反应元件绘制的控制顺序

反应元件绘制的控制顺序
EN

Stack Overflow用户
提问于 2016-08-17 03:53:34
回答 2查看 14.4K关注 0票数 11

如您所知,React组件并行呈现。没有保证他们完成渲染。

我想按照这样的顺序呈现以下组件:

  1. InterviewContentMain (因为它将呈现标头。我需要这个标题首先呈现,这样我就可以在呈现后的其他两个组件中对它进行操作。稍后,我将从其他两个组件的componentDidMount上运行一些JS等,这就是为什么我希望首先呈现这个组件)
  2. InterviewContainer (只应在InterviewContentMain呈现后呈现)
  3. TableOfContents (只应在InterviewContainer和InterviewContentMain呈现之后呈现)

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

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

代码语言:javascript
复制
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>
        )
    }
})

更新:

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

代码语言:javascript
复制
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>
        )
    }
})
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-17 04:45:35

如果要有条件地呈现组件,请将其包装为条件(无论是函数还是内联布尔表达式)。

你说:

TableOfContents (只应在InterviewContainer和InterviewContentMain呈现之后呈现)

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

代码语言:javascript
复制
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>
    )
}
票数 4
EN

Stack Overflow用户

发布于 2016-08-17 09:01:53

您正在调用setState in componentDidMount。在componentWillMount中调用它。在setState中立即调用render是一种反模式,因为componentDidMount是调用render的模式,参见这一讨论

我使用了稍微不同的语法,但这显然是可以理解的。

代码语言:javascript
复制
class InterviewContentMain ...
    this.state = {
      firstRendered: false
    }

    componentWillMount() {
      this.setState({ firstRendered: true });
    }

    render() {
      return (
      {this.state.firstRendered && 
       <InterviewContent />
      }
      );
    }

class InterviewContent ...
    this.state = {
      second: false
    }

    componentWillMount() {
      this.setState({ secondRendered: true });
    }

    render() {
      return (
      {this.state.secondRendered && 
       <TableOfContents />
      }
      );
    }

class TableOfContents ...

    render() {
      return (
       <div>Hello World in order</div>
      );
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38987847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档