React'e dinamik olarak alt bileşenleri ekleyin


89

Amacım, bileşenleri bir sayfaya / üst bileşene dinamik olarak eklemektir.

Bunun gibi bazı temel örnek şablonlarla başladım:

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

Burada SampleComponent, şablonda <div id="myId"></div>önceden yazılmış olan düğüme monte edilir App.js. Peki ya Uygulama bileşenine sınırsız sayıda bileşen eklemem gerekirse? Açıkçası, gerekli tüm div'lere orada oturamam .

Bazı öğreticileri okuduktan sonra, bileşenlerin nasıl oluşturulduğu ve dinamik olarak ana bileşene eklendiğini hala anlamıyorum. Bunu yapmanın bir yolu nedir?


2
Her iki bileşeninizin de farklı elemanlara monte edilmesinin bir nedeni var mı? React uygulamalarının% 99'u yalnızca bir ReactDOM.renderkez arar ve diğer tüm bileşenler 'kök' düğümün alt
öğelerini oluşturur

1
Hayır, şimdi bunun doğru olmadığını anlıyorum :)
Justin Trevein

Yanıtlar:


70

Bileşenlerinizi şu şekilde çocukken geçirmeniz gerekir:

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

Ve sonra bunları bileşenin gövdesine ekleyin:

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

HTML kodunu manuel olarak değiştirmenize gerek yok, React bunu sizin için yapacaktır. Bazı alt bileşenler eklemek istiyorsanız, yalnızca sahne donanımını değiştirmeniz veya bağlı olduğunu belirtmeniz gerekir. Örneğin:

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

});

2
Teşekkürler! Bileşenlerin render () içinde durumlarına göre tanımlanabileceği gerçeğini kaçırdım. Burada Yanıtınız (bileşenlerle durumunu doldurma bahseder) en eksiksiz biridir ve :) tam soruya cevap verir
Justin Trevein

Eklenen çocuklara nasıl yardımcı olunur?
BrightIntelDusk

1
Bunu takip etmek için: birkaç sekme ve düğmelerden açılan pencereler içeren tek bir sayfa uygulaması yapmak istersem, devam etmem ve bu bileşenleri oluşturmam (boş), onları gizlemem (bir şekilde) ve sonra yapmak için durumu değiştirmem gerekir. doğru zamanlarda "görünürler" mi? React'te çok sekmeli tek sayfalı bir uygulama yapmaya çalışacak olsaydınız, bunu düşünmenin en iyi yolu bu mu? Yoksa bir şey mi kaçırıyorum? Teşekkür ederim!
Elisabeth

1
@Elisabeth Evet, bu doğru. Aslında iki ana seçeneğiniz var: ya her zaman her şeyi oluşturun ya da sadece CSS kullanarak bir şeyleri gizleyin, koşullu olarak CSS sınıflarını veya satır içi stilleri uygulayın; veya uygulamanızın durumuna bağlı olarak React öğesi veya null döndürerek koşullu olarak render edin. Bu iki yaklaşımın artıları ve eksileri vardır ve genellikle ihtiyaçlarınıza bağlı olarak farklı bileşenler için aynı uygulamada her ikisi de kullanılır.
Nikolai Mavrenkov

1
Teşekkürler Nikolai! Bu, React ile ilgili aklımdaki şeyleri sağlamlaştırmaya gerçekten yardımcı oluyor. Uygulama tasarlamanın ve DOM hakkında düşünmenin, benim düz JavaScript ve jQuery ile kullandığımdan çok farklı bir yolu.
Elisabeth

7

Öncelikle document.body kullanmazdım . Bunun yerine boş bir kap ekleyin:

index.html:

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

Ardından, yalnızca öğenizi oluşturmayı seçin <App />:

main.js:

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

İçinden App.jsdiğer bileşenlerinizi içe aktarabilir ve DOM oluşturma kodunuzu tamamen yok sayabilirsiniz:

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

Ardından, kullanarak istediğiniz sayıda bileşenle gerekli bileşen dosyalarına aktararak programlı olarak etkileşime girebilirsiniz require.


Sorun değil, birinin kopyalayıp yapıştırdığını ve ardından saatlerce harcadığını görebiliyordum ...
Neil Twist

6

Çözümümü burada Chris'in cevabına göre paylaşıyorum. Umarım başkalarına yardım edebilir.

Alt öğeleri dinamik olarak JSX'ime eklemem gerekiyordu, ancak dönüş ifademdeki koşullu kontrollerden daha basit bir şekilde. Alt öğelerin henüz hazır olmaması durumunda bir yükleyici göstermek istiyorum. İşte burada:

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

Şimdi, ben de sadece koyabilirsiniz farkında mısın {pushMessages}ve {emailMessages}benim, doğrudan return()aşağıda, ama daha da koşullu içeriğe sahip varsayarak benim return()sadece darmadağın olur diye düşünüyoruz.


4

Öncelikle bir uyarı: React tarafından yönetilen DOM ile asla uğraşmamalısınız, bunu arayarak yaptığınız ReactDOM.render(<SampleComponent ... />);

React ile, SampleComponent'i doğrudan ana Uygulamada kullanmalısınız.

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

Bileşeninizin içeriği alakasızdır, ancak şu şekilde kullanılmalıdır:

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

Daha sonra bir liste kullanmak için uygulama bileşeninizi genişletebilirsiniz.

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

React belgelerine bakmanızı ve ardından "Başlarken" talimatlarını izlemenizi gerçekten tavsiye ederim. Bunun için harcadığınız zaman daha sonra karşılığını verecektir.

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


Dizi, eşleme yapmadan alt bileşeni nasıl dolduracak?
solanki ...

1
@solanki ... Bir eşleme, yalnızca liste React bileşenlerinin bir listesi olmadığında gereklidir. Buradaki liste iki SampleComponents'den oluşmaktadır ve bu nedenle bir eşleştirme gerektirmez. Liste bir isim listesiyse, React bileşenlerine bir eşleştirme gerektirirdi.
Neil Twist

@solanki ... Eşleştirmenin çıktısının sadece başka bir liste olduğunu unutmayın
Neil Twist

1
Tam olarak aradığım şey. Kullanım durumumun isteğe bağlı olarak JSX bileşenlerini <div>bir değişkene atanan boş bir değişkene itmesi gerekiyordu, bu daha sonra {content}dönüş ifademde olduğu gibi JSX'e eklenmişti . Boş bir dizi kullanmak çok kolaydı!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.