React.js में मूल घटक के लिए प्रॉपर पास करें


295

propsपुनरावृत्ति में घटनाओं का उपयोग करके एक बच्चे को उसके माता-पिता को पारित करने का एक सरल तरीका नहीं है ?

var Child = React.createClass({
  render: function() {
    <a onClick={this.props.onClick}>Click me</a>
  }
});

var Parent = React.createClass({
  onClick: function(event) {
    // event.component.props ?why is this not available?
  },
  render: function() {
    <Child onClick={this.onClick} />
  }
});

मुझे पता है कि आप इनपुट के मूल्य को पास करने के लिए नियंत्रित घटकों का उपयोग कर सकते हैं, लेकिन पूरी किट n 'कबाडल को पास करना अच्छा होगा। कभी-कभी बच्चे के घटक में सूचनाओं का एक सेट होता है जिसे आपको देखना नहीं होता है।

शायद घटना के लिए घटक को बांधने का एक तरीका है?

UPDATE - 9/1/2015

एक वर्ष से अधिक के लिए प्रतिक्रिया, और सेबेस्टियन Lorber के जवाब से प्रेरित का उपयोग कर के बाद, मैं है माता-पिता में कार्य करने के लिए तर्क के रूप में बच्चे के घटकों गुजर निष्कर्ष निकाला गया है नहीं तथ्य यह है जिस तरह से प्रतिक्रिया में, और न ही यह कभी एक अच्छा विचार था। मैंने जवाब बदल दिया है।


इसी तरह की समस्याओं के विभिन्न उत्तर हैं ( यहाँ और यहाँ ), लेकिन उनमें से कोई भी विशेष रूप से सुरुचिपूर्ण नहीं लगता
Bojangles

मैं सहमत हूं - श्रृंखला में उत्तीर्ण होने वाली घटनाएं महान हैं, लेकिन यह जानना शानदार होगा कि इस घटना की शुरुआत किस घटक से हुई।
केंडलबी

कृपया मेरे उत्तरों पर एक नज़र डालें, क्योंकि मुझे लगता है कि स्वीकृत उत्तर पर्याप्त नहीं है; stackoverflow.com/a/31756470/82609
सेबेस्टियन लॉर्बर

1
किट n 'कबाडल - सब कुछ शामिल करने के लिए। सभी घंटियाँ और सीटी पाने के लिए। द कम्बशन। urbandictionary.com/define.php?term=kit%20and%20caboodle
फ़िलिप Bartuzi

जवाबों:


268

संपादित करें : ES6 अद्यतन उदाहरणों के लिए अंतिम उदाहरण देखें।

यह उत्तर सीधे माता-पिता के बच्चे के रिश्ते के मामले को संभालता है। जब माता-पिता और बच्चे में संभावित रूप से बहुत अधिक मध्यस्थ होते हैं, तो इस उत्तर की जांच करें ।

अन्य समाधान बिंदु याद आ रहे हैं

जबकि वे अभी भी ठीक काम करते हैं, अन्य उत्तर कुछ महत्वपूर्ण याद कर रहे हैं।

पुनरावृत्ति में घटनाओं का उपयोग करके अपने माता-पिता के लिए एक बच्चे के सहारा को पास करने का एक सरल तरीका नहीं है?

माता-पिता के पास पहले से ही वह बच्चा है! : यदि बच्चे के पास एक प्रॉप है, तो यह इसलिए है क्योंकि उसके माता-पिता ने बच्चे को वह प्रॉप प्रदान किया है! आप बच्चे को माता-पिता के पास वापस क्यों भेजना चाहते हैं, जबकि माता-पिता के पास स्पष्ट रूप से वह प्रस्ताव है?

बेहतर कार्यान्वयन

बच्चा : यह वास्तव में उससे ज्यादा जटिल नहीं है।

var Child = React.createClass({
  render: function () {
    return <button onClick={this.props.onClick}>{this.props.text}</button>;
  },
});

एकल बच्चे के साथ अभिभावक : मूल्य का उपयोग करके यह बच्चे के पास जाता है

var Parent = React.createClass({
  getInitialState: function() {
     return {childText: "Click me! (parent prop)"};
  },
  render: function () {
    return (
      <Child onClick={this.handleChildClick} text={this.state.childText}/>
    );
  },
  handleChildClick: function(event) {
     // You can access the prop you pass to the children 
     // because you already have it! 
     // Here you have it in state but it could also be
     //  in props, coming from another parent.
     alert("The Child button text is: " + this.state.childText);
     // You can also access the target of the click here 
     // if you want to do some magic stuff
     alert("The Child HTML is: " + event.target.outerHTML);
  }
});

JsFiddle

बच्चों की सूची के साथ अभिभावक : आपके पास अभी भी वह सब कुछ है जो आपको माता-पिता की आवश्यकता है और बच्चे को अधिक जटिल बनाने की आवश्यकता नहीं है।

var Parent = React.createClass({
  getInitialState: function() {
     return {childrenData: [
         {childText: "Click me 1!", childNumber: 1},
         {childText: "Click me 2!", childNumber: 2}
     ]};
  },
  render: function () {
    var children = this.state.childrenData.map(function(childData,childIndex) {
        return <Child onClick={this.handleChildClick.bind(null,childData)} text={childData.childText}/>;
    }.bind(this));
    return <div>{children}</div>;
  },

  handleChildClick: function(childData,event) {
     alert("The Child button data is: " + childData.childText + " - " + childData.childNumber);
     alert("The Child HTML is: " + event.target.outerHTML);
  }
});

JsFiddle

इसका उपयोग करना this.handleChildClick.bind(null,childIndex)और फिर उपयोग करना भी संभव हैthis.state.childrenData[childIndex]

ध्यान दें कि हम एक nullसंदर्भ के साथ बाध्यकारी हैं क्योंकि अन्यथा प्रतिक्रिया इसके ऑटोबाइंडिंग सिस्टम से संबंधित चेतावनी जारी करती है। नल का उपयोग करने का मतलब है कि आप फ़ंक्शन संदर्भ को बदलना नहीं चाहते हैं। यह भी देखें

अन्य उत्तरों में इनकैप्सुलेशन और कपलिंग के बारे में

यह मेरे लिए कपलिंग और इनकैप्सुलेशन की अवधि में एक बुरा विचार है:

var Parent = React.createClass({
  handleClick: function(childComponent) {
     // using childComponent.props
     // using childComponent.refs.button
     // or anything else using childComponent
  },
  render: function() {
    <Child onClick={this.handleClick} />
  }
});

प्रॉप्स का उपयोग करना : जैसा कि मैंने ऊपर बताया है, आपके पास पहले से ही माता-पिता में प्रॉप्स हैं इसलिए प्रॉप्स तक पहुंचने के लिए पूरे बच्चे के घटक को पास करना बेकार है।

Refs का उपयोग करना : आपके पास पहले से ही ईवेंट में क्लिक लक्ष्य है, और ज्यादातर मामलों में यह पर्याप्त है। इसके अलावा, आप बच्चे पर सीधे रेफरी का उपयोग कर सकते हैं:

<Child ref="theChild" .../>

और माता-पिता के साथ DOM नोड का उपयोग करें

React.findDOMNode(this.refs.theChild)

अधिक उन्नत मामलों के लिए जहां आप बच्चे के कई रेफरी अभिभावक तक पहुंचना चाहते हैं, बच्चा कॉलबैक में सभी डोम नोड्स को सीधे पास कर सकता है।

घटक के पास एक इंटरफ़ेस (प्रॉपर) है और माता-पिता को बच्चे के आंतरिक कामकाज के बारे में कुछ भी ग्रहण नहीं करना चाहिए, जिसमें इसकी आंतरिक डोम संरचना भी शामिल है या जो डोम नोड्स घोषित करता है वह इसके लिए रेफरी है। एक बच्चे के रेफरी का उपयोग करने वाले माता-पिता का मतलब है कि आप कसकर 2 घटकों को जोड़ते हैं।

समस्या का वर्णन करने के लिए, मैं शैडो डोम के बारे में यह उद्धरण लूंगा , जिसका उपयोग ब्राउज़रों के अंदर स्लाइडर्स, स्क्रॉलबार, वीडियो प्लेयर जैसी चीजों को प्रस्तुत करने के लिए किया जाता है ...:

उन्होंने आपके, वेब डेवलपर के बीच एक सीमा बनाई और कार्यान्वयन विवरणों पर विचार किया जा सकता है, इस प्रकार आप के लिए दुर्गम है। हालांकि, ब्राउज़र इस वसीयत में सीमा पार कर सकता है। इस सीमा के साथ, वे सभी HTML तत्वों को एक ही अच्छी-पुरानी वेब तकनीकों का उपयोग करने में सक्षम कर रहे थे, जैसे आप चाहते हैं, वैसे ही divs और spans में से।

समस्या यह है कि यदि आप बच्चे के विवरण को माता-पिता में लीक होने देते हैं, तो आप माता-पिता को प्रभावित किए बिना बच्चे को फिर से तैयार करना बहुत कठिन बना देते हैं। यह एक पुस्तकालय लेखक के रूप में (या शैडो डोम के साथ एक ब्राउज़र संपादक के रूप में) इसका मतलब यह बहुत खतरनाक है क्योंकि आप क्लाइंट को बहुत अधिक उपयोग करने देते हैं, जिससे रेट्रोकोमपेबिलिटी को तोड़ने के बिना कोड को अपग्रेड करना बहुत कठिन हो जाता है।

यदि Chrome ने अपने स्क्रॉलबार को कार्यान्वित किया है, तो ग्राहक को उस स्क्रॉलबार के आंतरिक डोम नोड्स का उपयोग करने की अनुमति देता है, तो इसका मतलब है कि क्लाइंट के पास बस उस स्क्रॉलबार को तोड़ने की संभावना हो सकती है, और क्रोम को ऑटो-अपडेट करने के बाद ऐप आसानी से टूट जाएगा। स्क्रॉलबार ... इसके बजाय, वे केवल कुछ सुरक्षित चीजों तक पहुंच देते हैं जैसे कि सीएसएस के साथ स्क्रॉलबार के कुछ हिस्सों को कस्टमाइज़ करना।

किसी और चीज के इस्तेमाल के बारे में

कॉलबैक में पूरे घटक को पारित करना खतरनाक है और नौसिखिया डेवलपर्स को कॉल करने childComponent.setState(...)या childComponent.forceUpdate()माता-पिता के अंदर नए चर को असाइन करने, या ऐसा करने के लिए बहुत अजीब काम कर सकता है, जिससे पूरे ऐप के बारे में तर्क करना मुश्किल हो जाता है।


संपादित करें: ES6 उदाहरण

अब जितने लोग ES6 का उपयोग करते हैं, यहाँ ES6 वाक्य रचना के लिए एक ही उदाहरण हैं

बच्चा बहुत सरल हो सकता है:

const Child = ({
  onClick, 
  text
}) => (
  <button onClick={onClick}>
    {text}
  </button>
)

माता-पिता या तो एक वर्ग हो सकते हैं (और यह अंततः राज्य का प्रबंधन खुद कर सकते हैं, लेकिन मैं इसे यहां सहारा के रूप में पारित कर रहा हूं:

class Parent1 extends React.Component {
  handleChildClick(childData,event) {
     alert("The Child button data is: " + childData.childText + " - " + childData.childNumber);
     alert("The Child HTML is: " + event.target.outerHTML);
  }
  render() {
    return (
      <div>
        {this.props.childrenData.map(child => (
          <Child
            key={child.childNumber}
            text={child.childText} 
            onClick={e => this.handleChildClick(child,e)}
          />
        ))}
      </div>
    );
  }
}

लेकिन इसे सरल भी किया जा सकता है, अगर इसे राज्य का प्रबंधन करने की आवश्यकता नहीं है:

const Parent2 = ({childrenData}) => (
  <div>
     {childrenData.map(child => (
       <Child
         key={child.childNumber}
         text={child.childText} 
         onClick={e => {
            alert("The Child button data is: " + child.childText + " - " + child.childNumber);
                    alert("The Child HTML is: " + e.target.outerHTML);
         }}
       />
     ))}
  </div>
)

JsFiddle


PERF चेतावनी (ES5 / ES6 पर लागू): यदि आप उपयोग कर रहे हैं PureComponentया shouldComponentUpdate, उपरोक्त कार्यान्वयन डिफ़ॉल्ट रूप से अनुकूलित नहीं होंगे क्योंकि onClick={e => doSomething()}रेंडर चरण के दौरान सीधे उपयोग करते हुए , या बाइंडिंग करते हैं, क्योंकि यह पेरेंट रेंडर करने के लिए हर बार एक नया फ़ंक्शन बनाएगा। यदि आपके ऐप में यह एक अड़चन है, तो आप बच्चों को डेटा पास कर सकते हैं, और इसे "स्थिर" कॉलबैक (पैरेंट क्लास पर सेट, और thisक्लास कंस्ट्रक्टर में बाइंड किया गया) के अंदर रिइंस्टॉल PureComponentकर सकते हैं, ताकि ऑप्टिमाइज़ेशन किक कर सके, या आप अपने खुद के कार्यान्वित कर सकते हैं shouldComponentUpdateऔर सहारा तुलना चेक में कॉलबैक को अनदेखा कर सकते हैं।

आप पुन: उपयोग की गई लाइब्रेरी का भी उपयोग कर सकते हैं , जो ठीक ट्यून किए गए अनुकूलन प्राप्त करने के लिए उच्च आदेश घटक प्रदान करते हैं:

// A component that is expensive to render
const ExpensiveComponent = ({ propA, propB }) => {...}

// Optimized version of same component, using shallow comparison of props
// Same effect as React's PureRenderMixin
const OptimizedComponent = pure(ExpensiveComponent)

// Even more optimized: only updates if specific prop keys have changed
const HyperOptimizedComponent = onlyUpdateForKeys(['propA', 'propB'])(ExpensiveComponent)

इस स्थिति में आप बाल घटक को उपयोग करके अनुकूलित कर सकते हैं:

const OptimizedChild = onlyUpdateForKeys(['text'])(Child)

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

@KendallB को खुशी है कि आप मेरे जवाब से सहमत हैं :) How do I know which of my children was chosen among a group?यह वास्तव में मूल प्रश्न का हिस्सा नहीं है, लेकिन मैंने अपने उत्तर में समाधान को शामिल किया है। आपके संपादन के विपरीत, मुझे लगता है कि किसी सूची से निपटने के दौरान भी बच्चे को संशोधित करना आवश्यक नहीं है, जैसा कि आप bindसीधे माता-पिता में उपयोग कर सकते हैं ।
सेबेस्टियन लॉर्बर

मैंने आपके उत्तर को संपादित कर दिया, रेफ के बारे में। omerwazir.com/posts/react-getdomnode-replaced-with-findDOMNode
ffxsam

हाय @ SebastienLorber मैं भविष्य से आ रहा हूं। इस पंक्ति के onClick={this.handleChildClick.bind(null,childData)}बारे में आपने ऑटोबाइंडिंग के बारे में उल्लेख किया है यह अभी भी लागू है कि रिएक्ट ने क्लास मॉडल में शामिल नहीं किया है । मैंने बहुत सारा सामान पढ़ा है लेकिन यह हिस्सा अभी भी मुझे भ्रमित करता है। मैं class modelरास्ते से ES6 का उपयोग कर रहा हूं , इसलिए मैं बदल nullगया thisऔर मेरा कोड अभी भी काम कर रहा है। आप अपने कोड के उस हिस्से का ES6 शैली में अनुवाद कैसे करेंगे?
जॉनीक्यू

मैं भी इस कार्य को नवीनतम रिएक्ट में प्राप्त करने के लिए संघर्ष कर रहा हूं, जिसे बदलने की आवश्यकता है?
हुसैन दुविग्नेउ

143

अद्यतन (9/1/15): ओपी ने इस सवाल को थोड़ा सा लक्ष्य बनाया है। इसे फिर से अपडेट किया गया है। इसलिए, मुझे अपने उत्तर को अद्यतन करने के लिए जिम्मेदार लगता है।

सबसे पहले, आपके दिए गए उदाहरण का उत्तर:

हां, यह संभव है।

चाइल्ड्स अपडेट onClickहोने के लिए आप इसे हल कर सकते हैं this.props.onClick.bind(null, this):

var Child = React.createClass({
  render: function () {
    return <a onClick={this.props.onClick.bind(null, this)}>Click me</a>;
  }
});

आपके माता-पिता का ईवेंट हैंडलर घटक और इवेंट को इस तरह एक्सेस कर सकता है:

  onClick: function (component, event) {
    // console.log(component, event);
  },

JSBin स्नैपशॉट


लेकिन सवाल खुद भ्रामक है

माता-पिता पहले से ही जानते हैं कि बच्चे के props

प्रदान किए गए उदाहरण में यह स्पष्ट नहीं है क्योंकि वास्तव में कोई सहारा नहीं दिया जा रहा है। यह नमूना कोड पूछे जाने वाले प्रश्न का बेहतर समर्थन कर सकता है:

var Child = React.createClass({
  render: function () {
    return <a onClick={this.props.onClick}> {this.props.text} </a>;
  }
});

var Parent = React.createClass({
  getInitialState: function () {
    return { text: "Click here" };
  },
  onClick: function (event) {
    // event.component.props ?why is this not available? 
  },
  render: function() {
    return <Child onClick={this.onClick} text={this.state.text} />;
  }
});

इस उदाहरण में यह बहुत स्पष्ट हो जाता है कि आप पहले से ही जानते हैं कि बच्चे के रंग क्या होते हैं।

JSBin स्नैपशॉट


अगर यह सही मायने में एक बच्चे के सहारा का उपयोग करने के बारे में है ...

यदि यह सही मायने में चाइल्ड प्रॉप्स का उपयोग करने के बारे में है, तो आप चाइल्ड के साथ किसी भी हुकअप से बच सकते हैं।

JSX में एक प्रसार गुण API है जिसका उपयोग मैं अक्सर बाल जैसे घटकों पर करता हूं। यह सभी को लेता है propsऔर उन्हें एक घटक पर लागू करता है। बच्चा इस तरह दिखेगा:

var Child = React.createClass({
  render: function () {
    return <a {...this.props}> {this.props.text} </a>;
  }
});

आपको मूल में सीधे मानों का उपयोग करने की अनुमति देना:

var Parent = React.createClass({
  getInitialState: function () {
    return { text: "Click here" };
  },
  onClick: function (text) {
    alert(text);
  },
  render: function() {
    return <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />;
  }
});

JSBin स्नैपशॉट


और अतिरिक्त बाल घटकों को हुकअप करने के लिए आपको कोई अतिरिक्त कॉन्फ़िगरेशन की आवश्यकता नहीं है

var Parent = React.createClass({
  getInitialState: function () {
    return {
      text: "Click here",
      text2: "No, Click here",
    };
  },
  onClick: function (text) {
    alert(text);
  },
  render: function() {
    return <div>
      <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />
      <Child onClick={this.onClick.bind(null, this.state.text2)} text={this.state.text2} />
    </div>;
  }
});

JSBin स्नैपशॉट

लेकिन मुझे संदेह है कि यह आपका वास्तविक उपयोग मामला नहीं है। तो चलो आगे खुदाई करते हैं ...


एक मजबूत व्यावहारिक उदाहरण

प्रदान किए गए उदाहरण की सामान्य प्रकृति के बारे में बात करना मुश्किल है। मैंने एक घटक बनाया है जो ऊपर दिए गए प्रश्न के लिए एक व्यावहारिक उपयोग प्रदर्शित करता है, इसे बहुत ही प्रतिक्रियात्मक तरीके से कार्यान्वित किया गया है :

DTServiceCalculator वर्किंग उदाहरण
DTServiceCalculator रेपो

यह घटक एक साधारण सेवा कैलकुलेटर है। आप इसे सेवाओं की एक सूची (नाम और कीमतों के साथ) प्रदान करते हैं और यह कुल चयनित कीमतों की गणना करेगा।

बच्चे आनंद से अंजान हैं

ServiceItemइस उदाहरण में बाल-घटक है। यह बाहरी दुनिया के बारे में कई राय नहीं है। इसके लिए कुछ प्रॉपर की आवश्यकता होती है , जिनमें से एक को क्लिक करने पर फंक्शन कहा जाता है।

<div onClick={this.props.handleClick.bind(this.props.index)} />

यह प्रदान किए गए handleClickकॉलबैक के अलावा कुछ भी नहीं करता है , बशर्ते index[ स्रोत ]।

माता-पिता बच्चे हैं

DTServicesCalculatorमाता-पिता का घटक यह उदाहरण है। यह भी एक बच्चा है। चलो देखते हैं।

DTServiceCalculatorचाइल्ड-कंपोनेंट की सूची बनाता है ServiceItemऔर उन्हें प्रॉप्स [ स्रोत ] प्रदान करता है । यह माता-पिता का घटक है, ServiceItemलेकिन यह इस सूची को पारित करने वाले घटक का बाल-घटक है। यह डेटा का स्वामी नहीं है। तो यह फिर से घटक को उसके मूल-घटक स्रोत से निपटने का प्रतिनिधित्व करता है

<ServiceItem chosen={chosen} index={i} key={id} price={price} name={name} onSelect={this.props.handleServiceItem} />

handleServiceItemअनुक्रमणिका को पकड़ता है, बच्चे से पारित होता है, और इसे अपने माता-पिता को प्रदान करता है [ स्रोत ]

handleServiceClick (index) {
  this.props.onSelect(index);
}

मालिक सब जानते हैं

"स्वामित्व" की अवधारणा प्रतिक्रिया में एक महत्वपूर्ण है। मैं यहां इसके बारे में अधिक पढ़ने की सलाह देता हूं ।

मैंने जो उदाहरण दिखाया है, मैं उस घटना को तब तक संभालता रहता हूं जब तक कि हम उस घटक के पेड़ को संभाल नहीं लेते, जब तक कि हम उस घटक को प्राप्त नहीं कर लेते हैं जो राज्य का मालिक है।

जब हम अंत में वहां पहुंचते हैं, तो हम राज्य चयन / चयन रद्द कर देते हैं, जैसे [ स्रोत ]:

handleSelect (index) {
  let services = […this.state.services];
  services[index].chosen = (services[index].chosen) ? false : true;
  this.setState({ services: services });
}


निष्कर्ष

अपने बाहरी-सबसे घटकों को यथासंभव अपारदर्शी रखने की कोशिश करें। यह सुनिश्चित करने के लिए प्रयास करें कि उनके पास बहुत कम प्राथमिकताएं हैं कि कोई अभिभावक-घटक उन्हें कैसे लागू कर सकता है।

इस बात की जानकारी रखें कि आपके द्वारा हेरफेर किए जा रहे डेटा का मालिक कौन है। ज्यादातर मामलों में, आपको उस स्थिति के लिए पेड़ को संभालने वाले ईवेंट को सौंपने की आवश्यकता होगी जो उस स्थिति का मालिक है।

इसके अलावा: फ्लक्स पैटर्न इस प्रकार के आवश्यक हुकअप को कम करने का एक अच्छा तरीका है।


संक्षिप्त उत्तर के लिए धन्यवाद, यह वास्तव में मुझे प्रतिक्रिया को थोड़ा बेहतर समझने में मदद करता है! मेरे पास उसी तर्ज पर एक सवाल है। मैं पब / उप के लिए फ्लक्स का उपयोग कर रहा हूं। अपने उदाहरण की तरह पेरेंट तक चाइल्ड इवेंट हैंडलर को पास करने के बजाय, इसे 'एक्शन' के रूप में लागू करना और इसके लिए सुनना संभव है। क्या आप इसे फ्लक्स का एक अच्छा विकल्प और उपयोग मानेंगे?
पाथ्सोफेन्सिग्न

1
धन्यवाद @Pathsofdesign! यह निर्भर करेगा। फ्लक्स में नियंत्रक-दृश्य की यह अवधारणा है। इस उदाहरण में, Parentऐसा नियंत्रक-दृश्य हो सकता है, जबकि Childयह केवल एक गूंगा-दृश्य (घटक) है। केवल नियंत्रक-दृश्य के पास आवेदन का ज्ञान होना चाहिए। इस मामले में, आप अभी भी कार्रवाई से होकर गुजरेगा Parentलिए Childएक आधार के रूप में। जैसा कि एक्शन स्वयं का संबंध है, फ्लक्स के पास दृश्यों को अपडेट करने के लिए क्रियाओं के बीच बातचीत के लिए एक दृढ़ता से निर्धारित पैटर्न है। facebook.github.io/flux/docs/…
मंत्र

1
onClick={this.onClick.bind(null, this.state.text)}राज्य को माता-पिता के रूप में बांधने की आवश्यकता नहीं है। तो बस onClick={this.onClick}काम करेंगे। जहां onClick = ()=>{const text = this.state.text;..}माता
शिशिर अरोरा

25

ऐसा प्रतीत होता है कि एक सरल उत्तर है। इस पर विचार करो:

var Child = React.createClass({
  render: function() {
    <a onClick={this.props.onClick.bind(null, this)}>Click me</a>
  }
});

var Parent = React.createClass({
  onClick: function(component, event) {
    component.props // #=> {Object...}
  },
  render: function() {
    <Child onClick={this.onClick} />
  }
});

कुंजी घटना bind(null, this)पर बुला रही है this.props.onClick, माता-पिता से पारित हो गई है। अब, ऑनक्लिक फ़ंक्शन तर्कों को स्वीकार करता है component, और event। मुझे लगता है कि यह पूरी दुनिया में सबसे अच्छा है।

UPDATE: 9/1/2015

यह एक बुरा विचार था: बाल कार्यान्वयन विवरण को माता-पिता में लीक होने देना कभी एक अच्छा रास्ता नहीं था। देखिए सेबेस्टियन लॉबर का जवाब।


गलत तरीके से तर्क दिया (बदली हुई जगह)?
सूर्यास्त

1
@ तूफान यह पूरी तरह से ठीक नहीं है। पहला तर्क thisफ़ंक्शन के भीतर (जो वैसे भी आवश्यक नहीं है) के लिए बाध्य है , और दूसरा जब onClick कहा जाता है तो पहले तर्क के रूप में प्रस्तुत किया जाता है।
मानवबल

13

सवाल यह है कि बच्चे से माता-पिता के घटक तक तर्क कैसे पारित किया जाए। इस उदाहरण का उपयोग करना आसान है और परीक्षण किया गया है:

//Child component
class Child extends React.Component {
    render() {
        var handleToUpdate  =   this.props.handleToUpdate;
        return (<div><button onClick={() => handleToUpdate('someVar')}>Push me</button></div>
        )
    }
}

//Parent component
class Parent extends React.Component {
    constructor(props) {
        super(props);
        var handleToUpdate  = this.handleToUpdate.bind(this);
    }

    handleToUpdate(someArg){
        alert('We pass argument from Child to Parent: \n' + someArg);
    }

    render() {
        var handleToUpdate  =   this.handleToUpdate;
        return (<div>
          <Child handleToUpdate = {handleToUpdate.bind(this)} />
        </div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <Parent />,
        document.querySelector("#demo")
    );
}

JSFIDDLE को देखें


मेरे मामले में यह पास कॉलबैक फ़ंक्शन को क्लिक में भूल जाता है ()
लॉन्ग गुयेन

6

मूल रूप से आप बाल और माता-पिता से जानकारी भेजने के लिए प्रॉप्स का उपयोग करते हैं।

सभी अद्भुत उत्तरों को जोड़ते हुए, मैं एक सरल उदाहरण देता हूं जो कि रिएक्ट में बच्चे से माता-पिता के घटक तक के मूल्यों को समझाता है

App.js

class App extends React.Component {
      constructor(){
            super();
            this.handleFilterUpdate = this.handleFilterUpdate.bind(this);
            this.state={name:'igi'}
      }
      handleFilterUpdate(filterValue) {
            this.setState({
                  name: filterValue
            });
      }
   render() {
      return (
        <div>
            <Header change={this.handleFilterUpdate} name={this.state.name} />
            <p>{this.state.name}</p>
        </div>
      );
   }
}

Header.js

class Header extends React.Component {
      constructor(){
            super();
            this.state={
                  names: 'jessy'
            }
      }
      Change(event) {

      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

   render() {
      return (
       <button onClick={this.Change.bind(this)}>click</button>

      );
   }
}

main.js

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App.jsx';

ReactDOM.render(<App />, document.getElementById('app'));

Thats यह, अब आप अपने क्लाइंट से सर्वर पर मान पारित कर सकते हैं।

Header.js में बदलें फ़ंक्शन पर एक नज़र डालें

Change(event) {
      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

यह है कि आप क्लाइंट से सर्वर तक प्रॉप्स में वैल्यू को कैसे पुश करते हैं


क्या मुझे पता है कि आप क्लाइंट से सर्वर तक के मूल्यों को कैसे आगे
बढ़ाते हैं,

2

यहां पैरेंट कंस्ट्रक्टर में फ़ंक्शन बाइंडिंग का उपयोग करते हुए एक सरल 3 चरण ईएस 6 कार्यान्वयन है। यह पहला तरीका है जो आधिकारिक प्रतिक्रिया ट्यूटोरियल की सिफारिश करता है (यहां सार्वजनिक वर्ग फ़ील्ड सिंटैक्स भी शामिल नहीं है)। आप यह सारी जानकारी https://reactjs.org/docs/handling-events.html पर पा सकते हैं

पेरेंट फ़ंक्शंस को बांधना ताकि बच्चे उन्हें बुला सकें (और माता-पिता को डेटा पास करें!: D)

  1. पैरेंट कंस्ट्रक्टर में सुनिश्चित करें कि आप अपने द्वारा बनाए गए फ़ंक्शन को पेरेंट में बाँधते हैं
  2. बच्चे को एक प्रोपे के रूप में बाउंड फंक्शन पास करें (नो लैम्ब्डा क्योंकि हम फंक्शन में रेफरी पास कर रहे हैं)
  3. चाइल्ड ईवेंट (लैंबडा) से बाउंड फ़ंक्शन को कॉल करें! ईवेंट को निकाल दिए जाने पर हम फ़ंक्शन को कॉल कर रहे हैं। यदि हम ऐसा नहीं करते हैं तो फ़ंक्शन स्वचालित रूप से लोड पर चलेगा और ईवेंट पर ट्रिगर नहीं किया जाएगा।)

जनक का कार्य

handleFilterApply(filterVals){} 

जनक कंस्ट्रक्टर

this.handleFilterApply = this.handleFilterApply.bind(this);

पैगाम दिया बच्चे को

onApplyClick = {this.handleFilterApply}

चाइल्ड इवेंट कॉल

onClick = {() => {props.onApplyClick(filterVals)}

0

यह ऑनक्लिक इवेंट का उपयोग किए बिना एक उदाहरण है। मैं बस सहारा द्वारा बच्चे को एक कॉलबैक फ़ंक्शन पास करता हूं। उस कॉलबैक के साथ चाइल्ड कॉल भी डेटा वापस भेजती है। मैं डॉक्स में उदाहरणों से प्रेरित था ।

छोटा उदाहरण (यह एक tsx फाइलों में है, इसलिए प्रॉप्स और स्टेट्स को पूरी तरह से घोषित किया जाना चाहिए, मैंने कुछ लॉजिक घटकों से हटा दिए हैं, इसलिए यह कम कोड है)।

* अद्यतन: महत्वपूर्ण यह है कि कॉलबैक में बाँध दिया जाए, अन्यथा कॉलबैक में बच्चे की गुंजाइश है न कि माता-पिता की। केवल समस्या: यह "पुराना" माता-पिता है ...

लक्षण अभिभावक है:

interface SymptomChooserState {
  // true when a symptom was pressed can now add more detail
  isInDetailMode: boolean
  // since when user has this symptoms
  sinceDate: Date,
}

class SymptomChooser extends Component<{}, SymptomChooserState> {

  state = {
    isInDetailMode: false,
    sinceDate: new Date()
  }

  helloParent(symptom: Symptom) {
    console.log("This is parent of: ", symptom.props.name);
    // TODO enable detail mode
  }

  render() {
    return (
      <View>
        <Symptom name='Fieber' callback={this.helloParent.bind(this)} />
      </View>
    );
  }
}

लक्षण बच्चा है (बच्चे के प्रॉप्स में मैंने कॉलबैक फ़ंक्शन की घोषणा की है, फ़ंक्शन में चयनित सिम्प्टोम कॉलबैक कहा जाता है):

interface SymptomProps {
  // name of the symptom
  name: string,
  // callback to notify SymptomChooser about selected Symptom.
  callback: (symptom: Symptom) => void
}

class Symptom extends Component<SymptomProps, SymptomState>{

  state = {
    isSelected: false,
    severity: 0
  }

  selectedSymptom() {
    this.setState({ isSelected: true });
    this.props.callback(this);
  }

  render() {
    return (
      // symptom is not selected
      <Button
        style={[AppStyle.button]}
        onPress={this.selectedSymptom.bind(this)}>
        <Text style={[AppStyle.textButton]}>{this.props.name}</Text>
      </Button>
    );
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.