Javascript 在 React 中动态添加子组件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36651583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:22:22  来源:igfitidea点击:

Dynamically add child components in React

javascriptreactjsbabeljs

提问by Justin Trevein

My goal is to add components dynamically on a page/parent component.

我的目标是在页面/父组件上动态添加组件。

I started with some basic example template like this:

我从一些像这样的基本示例模板开始:

main.js:

主要.js:

var App = require('./App.js');
var SampleComponent = require('./SampleComponent.js');
ReactDOM.render(<App/>, document.body);
ReactDOM.render(<SampleComponent name="SomeName"/>, document.getElementById('myId'));

App.js:

应用程序.js:

var App = React.createClass({
    render: function() {
        return (
            <div>
                <h1>App main component! </h1>
                <div id="myId">myId div</div>
            </div>

        );
    }

});

SampleComponent.js:

示例组件.js:

var SampleComponent = React.createClass({
    render: function() {
        return (
            <div>
                <h1>Sample Component! </h1>
            </div>
        );
    }
});

Here SampleComponentis mounted to <div id="myId"></div>node, which is pre-written in App.jstemplate. But what if I need to add indefinite number of components to App component? Obviously I cannot have all the required divssitting there.

这里SampleComponent挂载到<div id="myId"></div>节点,这是预先写在App.js模板中的。但是如果我需要向 App 组件添加无限数量的组件怎么办?显然,我不能将所有必需的div放在那里。

After reading some tutorials I still have no understanding of how components are created and added to parent component dynamically. What is a way of doing it?

阅读了一些教程后,我仍然不了解组件是如何动态创建和添加到父组件的。这样做的方法是什么?

采纳答案by Nikolai Mavrenkov

You need to pass your components as children, like this:

您需要将组件作为子组件传递,如下所示:

var App = require('./App.js');
var SampleComponent = require('./SampleComponent.js');
ReactDOM.render(
    <App>
        <SampleComponent name="SomeName"/> 
    <App>, 
    document.body
);

And then append them in the component's body:

然后将它们附加到组件的主体中:

var App = React.createClass({
    render: function() {
        return (
            <div>
                <h1>App main component! </h1>
                {
                    this.props.children
                }
            </div>
        );
    }
});

You don't need to manually manipulate HTML code, React will do that for you. If you want to add some child components, you just need to change props or state it depends. For example:

你不需要手动操作 HTML 代码,React 会为你做这些。如果你想添加一些子组件,你只需要改变 props 或 state 它依赖。例如:

var App = React.createClass({

    getInitialState: function(){
        return [
            {id:1,name:"Some Name"}
        ]
    },

    addChild: function() {
        // State change will cause component re-render
        this.setState(this.state.concat([
            {id:2,name:"Another Name"}
        ]))
    }

    render: function() {
        return (
            <div>
                <h1>App main component! </h1>
                <button onClick={this.addChild}>Add component</button>
                {
                    this.state.map((item) => (
                        <SampleComponent key={item.id} name={item.name}/>
                    ))
                }
            </div>
        );
    }

});

回答by Chris

First, I wouldn't use document.body. Instead add an empty container:

首先,我不会使用 document.body。而是添加一个空容器:

index.html:

index.html:

<html>
    <head></head>
    <body>
        <div id="app"></div>
    </body>
</html>

Then opt to only render your <App />element:

然后选择仅呈现您的<App />元素:

main.js:

main.js:

var App = require('./App.js');
ReactDOM.render(<App />, document.getElementById('app'));

Within App.jsyou can import your other components and ignore your DOM render code completely:

App.js您可以在其中导入其他组件并完全忽略您的 DOM 渲染代码:

App.js:

App.js:

var SampleComponent = require('./SampleComponent.js');

var App = React.createClass({
    render: function() {
        return (
            <div>
                <h1>App main component!</h1>
                <SampleComponent name="SomeName" />
            </div>
        );
    }
});

SampleComponent.js:

SampleComponent.js:

var SampleComponent = React.createClass({
    render: function() {
        return (
            <div>
                <h1>Sample Component!</h1>
            </div>
        );
    }
});

Then you can programmatically interact with any number of components by importing them into the necessary component files using require.

然后,您可以通过使用require.

回答by Chris

Sharing my solution here, based on Chris' answer. Hope it can help others.

根据克里斯的回答,在这里分享我的解决方案。希望它可以帮助其他人。

I needed to dynamically append child elements into my JSX, but in a simpler way than conditional checks in my return statement. I want to show a loader in the case that the child elements aren't ready yet. Here it is:

我需要动态地将子元素附加到我的 JSX 中,但比我的 return 语句中的条件检查更简单。我想在子元素还没有准备好的情况下显示一个加载器。这里是:

export class Settings extends React.PureComponent {
  render() {
    const loading = (<div>I'm Loading</div>);
    let content = [];
    let pushMessages = null;
    let emailMessages = null;

    if (this.props.pushPreferences) {
       pushMessages = (<div>Push Content Here</div>);
    }
    if (this.props.emailPreferences) {
      emailMessages = (<div>Email Content Here</div>);
    }

    // Push the components in the order I want
    if (emailMessages) content.push(emailMessages);
    if (pushMessages) content.push(pushMessages);

    return (
      <div>
        {content.length ? content : loading}
      </div>
    )
}

Now, I do realize I could also just put {pushMessages}and {emailMessages}directly in my return()below, but assuming I had even more conditional content, my return()would just look cluttered.

现在,我确实意识到我也可以直接把{pushMessages}{emailMessages}放在我的return()下面,但假设我有更多的条件内容,我的return()看起来会很混乱。

回答by Neil Twist

Firstly a warning: you should never tinker with DOM that is managed by React, which you are doing by calling ReactDOM.render(<SampleComponent ... />);

首先警告:你永远不应该修改由 React 管理的 DOM,你正在通过调用 ReactDOM.render(<SampleComponent ... />);

With React, you should use SampleComponent directly in the main App.

使用 React,您应该直接在主应用程序中使用 SampleComponent。

var App = require('./App.js');
var SampleComponent = require('./SampleComponent.js');
ReactDOM.render(<App/>, document.body);

The content of your Component is irrelevant, but it should be used like this:

你的组件的内容是无关紧要的,但它应该像这样使用:

var App = React.createClass({
    render: function() {
        return (
            <div>
                <h1>App main component! </h1>
                <SampleComponent name="SomeName"/>
            </div>
        );
    }
});

You can then extend your app component to use a list.

然后,您可以扩展您的应用程序组件以使用列表。

var App = React.createClass({
    render: function() {
        var componentList = [
            <SampleComponent name="SomeName1"/>,
            <SampleComponent name="SomeName2"/>
        ]; // Change this to get the list from props or state
        return (
            <div>
                <h1>App main component! </h1>
                {componentList}
            </div>
        );
    }
});

I would really recommend that you look at the React documentation then follow the "Get Started" instructions. The time you spend on that will pay off later.

我真的建议您查看 React 文档,然后按照“入门”说明进行操作。你花在这上面的时间会在以后得到回报。

https://facebook.github.io/react/index.html

https://facebook.github.io/react/index.html