प्रतिक्रिया में डायनामिक रूप से बच्चे के घटक जोड़ें


86

मेरा लक्ष्य एक पृष्ठ / मूल घटक पर गतिशील रूप से घटकों को जोड़ना है।

मैंने इस तरह कुछ बुनियादी उदाहरण टेम्पलेट के साथ शुरुआत की:

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

यहां नोड पर SampleComponentमुहिम शुरू की गई <div id="myId"></div>है, जो App.jsटेम्पलेट में पहले से लिखा हुआ है। लेकिन क्या होगा अगर मुझे ऐप घटक में अनिश्चित संख्या में घटकों को जोड़ने की आवश्यकता है? जाहिर है कि मेरे पास वहां बैठे सभी जरूरी डिविजन नहीं हो सकते ।

कुछ ट्यूटोरियल पढ़ने के बाद भी मुझे इस बात की कोई समझ नहीं है कि घटकों को गतिशील रूप से कैसे बनाया और जोड़ा जाता है। इसे करने का एक तरीका क्या है?


2
क्या कोई कारण है कि आपके दोनों घटक अलग-अलग तत्वों को माउंट करते हैं? 99% रिएक्ट ऐप्स केवल ReactDOM.renderएक बार कॉल करते हैं और अन्य सभी घटक 'रूट' नोड के बच्चे हैं
azium

1
नहीं, अब मैं समझता हूं कि यह सही तरीका नहीं है :)
जस्टिन ट्रेविन

जवाबों:


67

आपको अपने घटकों को बच्चों के रूप में पारित करने की आवश्यकता है, जैसे:

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

और फिर उन्हें घटक के शरीर में जोड़ दें:

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

आपको मैन्युअल रूप से HTML कोड में हेरफेर करने की आवश्यकता नहीं है, रिएक्ट आपके लिए यही करेगा। यदि आप कुछ बाल घटकों को जोड़ना चाहते हैं, तो आपको बस सहारा बदलने की जरूरत है या यह निर्भर करता है। उदाहरण के लिए:

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
धन्यवाद! मैंने इस तथ्य को याद किया कि घटकों को उनके राज्य के आधार पर रेंडर () में परिभाषित किया जा सकता है। आपका उत्तर यहां सबसे पूर्ण है (घटकों के साथ आबादी वाले राज्य का उल्लेख है) और सवाल का सटीक उत्तर देता है :)
जस्टिन ट्रेविन

आप उन बच्चों को कैसे पास करते हैं, जिन्हें जोड़ा गया है?
BrightIntelDusk

तो इस पर फॉलो अप करने के लिए: यदि मैं एक एकल पेज ऐप बनाना चाहता हूं जिसमें बटन से कई टैब और पॉपअप विंडो हैं, तो मुझे आगे बढ़ने और उन घटकों (खाली) को प्रस्तुत करने, उन्हें छिपाने (किसी तरह) छिपाने और फिर राज्य बनाने के लिए संशोधित करना होगा उन्हें सही समय पर "दिखाई" देता है? यदि आप रिएक्ट में एक बहु-टैब वाला सिंगल पेज ऐप बनाने की कोशिश कर रहे थे, तो क्या यह सोचने का सबसे अच्छा तरीका है? या क्या मैं कुछ न कुछ भूल रहा हूं? धन्यवाद!
एलिजाबेथ

1
@ एलिसबेथ हाँ, यह सही है। आपके पास वास्तव में दो मुख्य विकल्प हैं: या तो हमेशा सब कुछ प्रस्तुत करें और बस सीएसएस का उपयोग करके चीजों को छिपाएं, सशर्त रूप से सीएसएस कक्षाएं या इनलाइन शैलियों को लागू करना; या चीजों को सशर्त रूप से प्रस्तुत करना, आपकी एप्लिकेशन स्थिति के आधार पर प्रतिक्रिया तत्व या अशक्त लौटाना। इन दो दृष्टिकोणों में पेशेवरों और विपक्ष हैं और अक्सर अपनी आवश्यकताओं के आधार पर विभिन्न घटकों के लिए एक ही ऐप में दोनों का उपयोग किया जाता है।
निकोलाई माव्रेनकोव

1
शुक्रिया निकोलाई! यह वास्तव में प्रतिक्रिया के बारे में मेरे दिमाग में चीजों को ठोस बनाने में मदद करता है। यह ऐप्स को डिज़ाइन करने और डोम के बारे में सोचने का एक बहुत ही अलग तरीका है, जिसका उपयोग मैं सादे जावास्क्रिप्ट और jQuery के साथ करता हूँ।
एलिजाबेथ

6

सबसे पहले, मैं document.body का उपयोग नहीं करेगा । इसके बजाय एक खाली कंटेनर जोड़ें:

index.html:

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

तब केवल अपने <App />तत्व को प्रस्तुत करने का विकल्प चुनें :

main.js:

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

भीतर 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:

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

तब आप किसी भी संख्या में घटकों के साथ प्रोग्राम कर उन्हें आवश्यक घटक फ़ाइलों का उपयोग करके आयात कर सकते हैं require


कोई बात नहीं, मैं बस किसी को कॉपी-पेस्ट करते देख सकता था और फिर उस पर घंटों बिता सकता था ...
नील ट्विस्ट

6

क्रिस के जवाब के आधार पर, यहां मेरे समाधान को साझा करना। आशा है कि यह दूसरों की मदद कर सकता है।

मुझे अपने जेएसएक्स में बाल तत्वों को गतिशील रूप से जोड़ने की आवश्यकता थी, लेकिन मेरे रिटर्न स्टेटमेंट में सशर्त जांच की तुलना में सरल तरीके से। मैं इस मामले में एक लोडर दिखाना चाहता हूं कि बाल तत्व अभी तक तैयार नहीं हैं। यह रहा:

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

अब, मुझे लगता है कि मैं भी बस {pushMessages}और {emailMessages}सीधे अपने return()नीचे रख सकता हूं , लेकिन मुझे लगता है कि मेरे पास और भी अधिक सशर्त सामग्री थी, मैं return()बस अव्यवस्थित दिखूंगा।


4

सबसे पहले एक चेतावनी: आपको रिएक्ट द्वारा प्रबंधित डोम के साथ कभी छेड़छाड़ नहीं करनी चाहिए, जिसे आप कॉल करके कर रहे हैं ReactDOM.render(<SampleComponent ... />);

React के साथ, आपको मुख्य ऐप में सीधे नमूना.कॉम का उपयोग करना चाहिए।

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

आपके घटक की सामग्री अप्रासंगिक है, लेकिन इसका उपयोग इस तरह किया जाना चाहिए:

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

फिर आप किसी सूची का उपयोग करने के लिए अपने एप्लिकेशन घटक का विस्तार कर सकते हैं।

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

मैं वास्तव में सिफारिश करूंगा कि आप रिएक्ट डॉक्यूमेंटेशन देखें और फिर "गेट स्टार्टेड" निर्देशों का पालन करें। आप जिस समय पर खर्च करेंगे, बाद में भुगतान करेंगे।

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


सरणी बिना मानचित्रण के बच्चे को कैसे पॉप्युलेट करेगा?
सोलंकी ...

1
@solanki ... सूची की प्रतिक्रिया घटकों की सूची नहीं होने पर मानचित्रण आवश्यक है। यहाँ सूची दो SampleComponents की है, जिसके लिए मैपिंग की आवश्यकता नहीं है। यदि सूची नामों की सूची थी, तो इसके लिए रिएक्ट घटकों को मैपिंग की आवश्यकता होगी।
नील ट्विस्ट

@solanki ... याद रखें कि मैपिंग का आउटपुट केवल एक और सूची है
नील ट्विस्ट

1
ठीक वही जो मेरे द्वारा खोजा जा रहा था। मेरे उपयोग के मामले को वैकल्पिक रूप से JSX घटकों <div>को एक वैरिएबल को खाली करने के लिए पुश करने की आवश्यकता थी, जो तब JSX {content}में मेरे रिटर्न स्टेटमेंट में डाला गया था । खाली सरणी का उपयोग करना इतना आसान था!
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.