Füge untergeordnete Komponenten in React dynamisch hinzu

Lesezeit: 6 Minuten

Benutzer-Avatar
Justin Treven

Mein Ziel ist es, Komponenten dynamisch auf einer Seite/übergeordneten Komponente hinzuzufügen.

Ich begann mit einer einfachen Beispielvorlage wie dieser:

main.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:

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

        );
    }

});

SampleComponent.js:

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

Hier SampleComponent montiert ist <div id="myId"></div> Knoten, der vorab eingeschrieben ist App.js Schablone. Aber was ist, wenn ich der App-Komponente eine unbegrenzte Anzahl von Komponenten hinzufügen muss? Offensichtlich kann ich nicht alle erforderlichen haben div Dort sitzen.

Nachdem ich einige Tutorials gelesen habe, habe ich immer noch kein Verständnis dafür, wie Komponenten erstellt und dynamisch zur übergeordneten Komponente hinzugefügt werden. Was ist ein Weg, es zu tun?

  • Gibt es einen Grund, warum beide Komponenten an unterschiedlichen Elementen montiert werden? 99 % der React-Apps rufen nur an ReactDOM.render einmal und alle anderen Komponenten sind Kinder des ‘Root’-Knotens

    – Asium

    15. April 2016 um 15:55 Uhr

  • Nein, ich verstehe jetzt, dass dies nicht der richtige Weg ist 🙂

    – Justin Trevein

    15. April 2016 um 23:12 Uhr

Benutzer-Avatar
Nikolai Mavrenkow

Sie müssen Ihre Komponenten wie folgt als Kinder übergeben:

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

Und fügen Sie sie dann in den Körper der Komponente ein:

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

Sie müssen den HTML-Code nicht manuell manipulieren, React erledigt das für Sie. Wenn Sie einige untergeordnete Komponenten hinzufügen möchten, müssen Sie nur die Requisiten ändern oder angeben, dass es davon abhängt. Zum Beispiel:

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

});

  • Vielen Dank! Ich habe die Tatsache übersehen, dass Komponenten in render() basierend auf ihrem Zustand definiert werden können. Ihre Antwort hier ist die vollständigste (erwähnt den Füllzustand mit Komponenten) und beantwortet die Frage genau 🙂

    – Justin Trevein

    15. April 2016 um 23:17 Uhr

  • Wie geben Sie Requisiten an die angehängten Kinder weiter?

    – BrightIntelDusk

    11. Dezember 2017 um 23:29 Uhr


  • Um dem nachzugehen: Wenn ich eine Single-Page-App mit mehreren Registerkarten und Popup-Fenstern aus Schaltflächen erstellen möchte, muss ich diese Komponenten (leer) rendern, sie (irgendwie) ausblenden und dann den Status ändern, um sie zu erstellen sie “erscheinen” zur richtigen Zeit? Wenn Sie versuchen würden, eine Single-Page-App mit mehreren Registerkarten in React zu erstellen, ist das die beste Art, darüber nachzudenken? Oder übersehe ich etwas? Vielen Dank!

    – Elisabeth

    23. März 2018 um 19:11 Uhr

  • @Elisabeth Ja, das stimmt. Sie haben eigentlich zwei Hauptoptionen: Entweder immer alles rendern und Dinge einfach mit CSS ausblenden, CSS-Klassen oder Inline-Stile bedingt anwenden; oder rendern Sie Dinge bedingt und geben Sie das React-Element oder null zurück, abhängig von Ihrem App-Status. Diese beiden Ansätze haben Vor- und Nachteile und werden je nach Bedarf häufig in derselben App für verschiedene Komponenten verwendet.

    – Nikolai Mavrenkov

    23. März 2018 um 23:03 Uhr

  • Danke Nikolaj! Das hilft wirklich, die Dinge in meinem Kopf über React zu festigen. Es ist eine ganz andere Art, Apps zu entwerfen und über das DOM nachzudenken, als ich es mit einfachem JavaScript und jQuery gewohnt bin.

    – Elisabeth

    25. März 2018 um 1:32 Uhr

Teilen Sie hier meine Lösung, basierend auf der Antwort von Chris. Hoffe es kann anderen helfen.

Ich musste untergeordnete Elemente dynamisch an mein JSX anhängen, aber auf einfachere Weise als bedingte Prüfungen in meiner return-Anweisung. Ich möchte einen Loader zeigen, falls die untergeordneten Elemente noch nicht fertig sind. Hier ist es:

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

Jetzt ist mir klar, dass ich es auch einfach setzen könnte {pushMessages} und {emailMessages} direkt in meinem return() unten, aber vorausgesetzt, ich hätte noch mehr bedingten Inhalt, my return() würde nur unordentlich aussehen.

Benutzer-Avatar
Chris

Zuerst, Ich würde document.body nicht verwenden. Fügen Sie stattdessen einen leeren Container hinzu:

index.html:

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

Entscheiden Sie sich dann dafür, nur Ihre zu rendern <App /> Element:

main.js:

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

Innerhalb App.js Sie können Ihre anderen Komponenten importieren und Ihren DOM-Rendercode vollständig ignorieren:

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:

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

Anschließend können Sie programmgesteuert mit einer beliebigen Anzahl von Komponenten interagieren, indem Sie sie mithilfe von in die erforderlichen Komponentendateien importieren require.

Zunächst eine Warnung: Sie sollten niemals an DOM basteln, das von React verwaltet wird, was Sie durch Aufrufen tun ReactDOM.render(<SampleComponent ... />);

Mit React sollten Sie SampleComponent direkt in der Haupt-App verwenden.

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

Der Inhalt Ihrer Komponente ist irrelevant, aber sie sollte wie folgt verwendet werden:

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

Anschließend können Sie Ihre App-Komponente erweitern, um eine Liste zu verwenden.

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

Ich würde wirklich empfehlen, dass Sie sich die React-Dokumentation ansehen und dann den Anweisungen “Get Started” folgen. Die Zeit, die Sie dafür aufwenden, zahlt sich später aus.

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

1217170cookie-checkFüge untergeordnete Komponenten in React dynamisch hinzu

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy