jjzjj

javascript - 控制 React 组件渲染的顺序

coder 2024-07-16 原文

如你所知,React 组件是并行渲染的。无法保证它们会完成渲染。

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

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

    。我需要先呈现此标题,以便在呈现后我可以在我的其他两个组件中对其进行操作。我将运行一些它上面的 JS,等等。后来来自其他两个组件的 componentDidMount,所以这就是为什么我希望它首先呈现)

  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>
        )
    }
})

更新:

这是我试过的。虽然它们都 3 呈现,但我仍然得到 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>
        )
    }
})

最佳答案

如果你想有条件地渲染一个组件,把它包裹在一个条件中(无论是一个函数还是一个内联 bool 表达式)

你说:

TableOfContents (should only render after InterviewContainer and InterviewContentMain have rendered)

.. 所以在 TableOfContents 父容器的 render 方法中,检查某些值是否为真,就像在 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>
    )
}

关于javascript - 控制 React 组件渲染的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38987847/

有关javascript - 控制 React 组件渲染的顺序的更多相关文章

  1. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  4. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  5. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  6. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  7. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  8. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  9. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  10. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

随机推荐