सिबलिंग / पैरेंट एलिमेंट्स के लिए फॉर्म एलिमेंट स्टेट पास करने का सही तरीका क्या है?


186
  • मान लीजिए कि मेरे पास एक रिएक्ट क्लास पी है, जो दो बच्चे वर्गों, सी 1 और सी 2 का प्रतिपादन करता है।
  • C1 में एक इनपुट फ़ील्ड है। मैं इस इनपुट फ़ील्ड को फू के रूप में संदर्भित करूंगा।
  • मेरा लक्ष्य फू में परिवर्तन के लिए C2 पर प्रतिक्रिया देना है।

मैं दो समाधानों के साथ आया हूँ, लेकिन दोनों में से कोई भी सही नहीं है।

पहला उपाय:

  1. असाइन पी एक राज्य, state.input
  2. onChangeP में एक फंक्शन बनाएं , जो किसी ईवेंट में होता है और सेट होता है state.input
  3. onChangeC1 के रूप में इसे पास करें props, और F1 this.props.onChangeको C1 को बांधने दें onChange

यह काम। जब भी फू का मूल्य बदलता है, यह setStateपी में ट्रिगर करता है , तो पी में C2 पास करने के लिए इनपुट होगा।

लेकिन यह एक ही कारण के लिए काफी सही नहीं लगता है: मैं एक बच्चे के तत्व से एक मूल तत्व की स्थिति निर्धारित कर रहा हूं। यह प्रतिक्रिया के डिजाइन सिद्धांत को धोखा देता है: एकल-दिशा डेटा प्रवाह।
क्या यह है कि मैं इसे कैसे करने वाला हूं, या एक और अधिक प्रतिक्रिया-प्राकृतिक समाधान है?

दूसरा उपाय:

पी में सिर्फ फू डालें।

लेकिन क्या यह एक डिजाइन सिद्धांत है जिसका मुझे पालन करना चाहिए जब मैं अपने ऐप को तैयार करता हूं - सभी फॉर्म तत्वों renderको उच्चतम-स्तरीय वर्ग में डाल रहा हूं ?

मेरे उदाहरण की तरह, अगर मेरे पास C1 का एक बड़ा प्रतिपादन है, तो मैं वास्तव में P के पूरे renderC1 को renderसिर्फ इसलिए नहीं रखना चाहता क्योंकि C1 में एक तत्व है।

मैं इसे कैसे करूं?


मैं बिल्कुल वैसा ही काम करने वाला हूं और इसके बावजूद, यह ठीक से काम कर रहा है, मुझे लगता है कि यह सिर्फ एक विशालकाय हैक है
Mirko

जवाबों:


198

इसलिए, अगर मैं आपको सही तरीके से समझ रहा हूं, तो आपका पहला समाधान यह सुझाव दे रहा है कि आप अपने रूट कंपोनेंट में स्टेट रख रहे हैं? मैं रिएक्ट के निर्माताओं के लिए बात नहीं कर सकता, लेकिन आम तौर पर, मुझे यह एक उचित समाधान लगता है।

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

राज्य को पदानुक्रम में और अधिक बनाए रखने, और इसे अपडेट करने के माध्यम से अपडेट करने से, आपका डेटा प्रवाह अभी भी बहुत अधिक अप्रत्यक्ष है, आप बस रूट घटक में घटनाओं का जवाब दे रहे हैं, आप वास्तव में डेटा को दो तरह से बाध्यकारी नहीं कर रहे हैं, आप रूट घटक को बता रहे हैं कि "हे, यहाँ कुछ घटित हुआ, मूल्यों की जाँच करें" या आप राज्य को अपडेट करने के लिए बाल घटक में कुछ डेटा की स्थिति को पार कर रहे हैं। आपने C1 में स्थिति बदल दी है, और आप चाहते हैं कि C2 को इसके बारे में जानकारी हो, इसलिए, राज्य को रूट घटक में अपडेट करके और फिर से रेंडर करके, C2 के प्रॉम्प्स अब सिंक में हैं क्योंकि राज्य को रूट घटक में अद्यतन किया गया था और साथ पारित किया गया था ।

class Example extends React.Component {
  constructor (props) {
    super(props)
    this.state = { data: 'test' }
  }
  render () {
    return (
      <div>
        <C1 onUpdate={this.onUpdate.bind(this)}/>
        <C2 data={this.state.data}/>
      </div>
    )
  }
  onUpdate (data) { this.setState({ data }) }
}

class C1 extends React.Component {
    render () {
      return (
        <div>
          <input type='text' ref='myInput'/>
          <input type='button' onClick={this.update.bind(this)} value='Update C2'/>
        </div>
      )
    }
    update () {
      this.props.onUpdate(this.refs.myInput.getDOMNode().value)
    }
})

class C2 extends React.Component {
    render () {
      return <div>{this.props.data}</div>
    }
})

ReactDOM.renderComponent(<Example/>, document.body)

5
कोई दिक्कत नहीं है। मैं वास्तव में इस पोस्ट को लिखने के बाद वापस चला गया और कुछ दस्तावेज़ीकरण को फिर से शुरू किया, और यह उनकी सोच और सर्वोत्तम प्रथाओं के साथ इनलाइन लगता है। रिएक्ट का वास्तव में उत्कृष्ट दस्तावेज है, और हर बार जब मैं सोचता हूं कि कुछ कहां जाना चाहिए, तो उन्होंने आम तौर पर इसे डॉक्स में कहीं कवर किया है। यहाँ राज्य पर अनुभाग देखें, facebook.github.io/react/docs/…
3131 को कैद करें

@captray लेकिन क्या बारे में, अगर C2एक है getInitialStateडेटा के लिए और अंदर renderइसे इस्तेमाल करता है this.state.data?
दिमित्री पॉलुस्किन

2
@DmitryPolushkin यदि मैं आपके प्रश्न को सही ढंग से समझ रहा हूं, तो आप अपने रूट कंपोनेंट से C2 तक के डेटा को प्रॉपर के रूप में पास करना चाहते हैं। C2 में, वह डेटा प्रारंभिक स्थिति के रूप में सेट किया जाएगा (यानी getInitialState: function () {return {someData: this.props.dataFromParentThatWillChange}} और आप घटक को लागू करना चाहेंगे ।ReceiveProps और इस प्रॉप को अपडेट करने के लिए नए प्रॉप्स के साथ कॉल करें। सी 2 में राज्य। चूंकि मैंने शुरू में जवाब दिया था, मैं फ्लक्स का उपयोग कर रहा हूं, और अत्यधिक अनुशंसा करेगा कि आप इसे भी देखें। यह आपके घटकों को साफ करता है और आपके राज्य के बारे में सोचने के तरीके को बदल देगा।
कैच करें

3
@DmitryPolushkin मैं इसे फॉलोअप करना चाहता था। facebook.github.io/react/tips/… यह ठीक है जब तक आप जानते हैं कि आप क्या कर रहे हैं और आप जानते हैं कि डेटा बदलने जा रहा है, लेकिन कई स्थितियों में आप शायद चीजों को स्थानांतरित कर सकते हैं। यह नोट करना भी महत्वपूर्ण है कि आपको इसे पदानुक्रम के रूप में नहीं बनाना है। आप DOM में विभिन्न स्थानों पर C1 और C2 को माउंट कर सकते हैं, और वे दोनों कुछ डेटा पर घटनाओं को बदलने के लिए सुन सकते हैं। मैं बहुत से लोगों को पदानुक्रमित घटकों के लिए धक्का देता हूं जब उन्हें उनकी आवश्यकता नहीं होती है।
कैद

5
उपरोक्त कोड में 2 बग हैं - जिनमें से दोनों सही संदर्भ में "इस" को शामिल नहीं करते हैं, मैंने उपरोक्त सुधार किए हैं और किसी के लिए भी जिन्हें कोडपेन प्रदर्शन की आवश्यकता है: codepen.io/anon/pen/wJrRpZ-editors=0011
एलेक्स एच।

34

एक ऐप बनाने के लिए रिएक्ट का इस्तेमाल करने के बाद, मैं इस सवाल से कुछ विचार साझा करना चाहता हूं जो मैंने आधे साल पहले पूछा था।

मैं आपको पढ़ने की सलाह देता हूं

पहली पोस्ट यह समझने में बेहद मददगार है कि आपको अपने रिएक्ट ऐप को कैसे तैयार करना चाहिए।

फ्लक्स इस सवाल का जवाब देता है कि आपको अपने रिएक्ट ऐप को इस तरह से क्यों बनाना चाहिए (जैसे कि इसे कैसे तैयार किया जाए)। प्रतिक्रिया प्रणाली का केवल 50% है, और फ्लक्स के साथ आपको पूरी तस्वीर देखने के लिए मिलती है और देखें कि वे एक सुसंगत प्रणाली का गठन कैसे करते हैं।

वापस सवाल पर।

मेरे पहले समाधान के लिए, हैंडलर को रिवर्स दिशा में जाने देना पूरी तरह से ठीक है , क्योंकि डेटा अभी भी सिंगल-दिशा में जा रहा है।

हालांकि, चाहे हैंडलर को पी में सेटस्टैट को ट्रिगर करने देना आपकी स्थिति के आधार पर सही या गलत हो सकता है।

यदि ऐप एक साधारण मार्कडाउन कनवर्टर है, तो C1 कच्चा इनपुट है और C2 HTML आउटपुट है, तो C1 को P में एक सेटस्टैट को ट्रिगर करने देना ठीक है, लेकिन कुछ का तर्क हो सकता है कि यह ऐसा करने का अनुशंसित तरीका नहीं है।

हालांकि, अगर अनुप्रयोग एक कार्यसूची है, सी 1 एक नया कार्य करने की बनाने के लिए इनपुट किया जा रहा है, सी 2 HTML में कार्यसूची, तो आप शायद हैंडलर के लिए दो स्तर पी से ऊपर जाने के लिए चाहते हैं - करने के लिए dispatcherहै, जो जाने storeअद्यतन data store, जो तब P को डेटा भेजता है और विचारों को पॉप्युलेट करता है। वह फ्लक्स लेख देखें। यहाँ एक उदाहरण है: फ्लक्स - टोडोएमवीसी

आम तौर पर, मैं टूडू सूची उदाहरण में वर्णित तरीका पसंद करता हूं। आपके ऐप में जितना कम स्टेट उतना बेहतर होगा।


7
मैं अक्सर रिएक्ट और फ्लक्स दोनों पर प्रस्तुतियों में इस पर चर्चा करता हूं। जिस बिंदु पर मैं जोर देने की कोशिश करता हूं, वह वही है जो आपने ऊपर वर्णित किया है, और वह है व्यू स्टेट और एप्लिकेशन स्टेट का पृथक्करण। ऐसी परिस्थितियाँ हैं जहाँ चीजें केवल दृश्य स्थिति से अनुप्रयोग राज्य बनने के लिए संक्रमण कर सकती हैं, विशेषकर उन स्थितियों में जहाँ आप UI की स्थिति (जैसे पूर्व निर्धारित मान) को सहेज रहे हैं। मुझे लगता है कि यह भयानक है कि आप एक साल बाद अपने विचारों के साथ वापस आए। +1
1

@ captray तो क्या हम कह सकते हैं कि redux सभी परिस्थितियों में प्रतिक्रिया की तुलना में शक्तिशाली है? उनके सीखने की अवस्था के बावजूद ... (जावा से आने वाले)
ब्रूस सन

मुझे नहीं पता तुम्हारा क्या मतलब है। वे दो अलग-अलग चीजों को बहुत अच्छी तरह से संभालते हैं, और चिंताओं का उचित पृथक्करण है।
कैद

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

1
@wayofthefuture आपके कोड को देखे बिना, मैं कह सकता हूं कि मैं बहुत अच्छे स्पेगेटी jQuery की तरह स्पेगेटी रिएक्ट का एक बहुत कुछ देखता हूं। सबसे अच्छी सलाह जो मैं पेश कर सकता हूं वह है एसआरपी का पालन करना। अपने घटकों को यथासंभव सरल बनाएं; गूंगा प्रतिपादन घटक यदि आप कर सकते हैं। मैं एक <DataProvider /> घटक की तरह अमूर्तता के लिए भी धक्का देता हूं। यह एक काम अच्छी तरह से करता है। डेटा प्रदान करें। यह आमतौर पर 'रूट' घटक बन जाता है और सहारा (परिभाषित अनुबंध) के रूप में बच्चों (और क्लोनिंग) का लाभ उठाकर डेटा को नीचे कर देता है। अंततः, पहले सर्वर पर सोचने की कोशिश करें। यह बेहतर डेटा संरचनाओं के साथ आपके जेएस को बहुत क्लीनर बना देगा।
कैद

5

पहला समाधान, साथ माता पिता घटक में राज्य में रखते हुए , है सही । हालांकि, अधिक जटिल समस्याओं के लिए, आपको कुछ राज्य प्रबंधन पुस्तकालय के बारे में सोचना चाहिए , Redux सबसे लोकप्रिय है जिसका उपयोग प्रतिक्रिया के साथ किया जाता है।


माना। मेरी प्रतिक्रिया तब लिखी गई जब ज्यादातर "शुद्ध प्रतिक्रिया" में चीजें लिख रहे थे। फ्लक्सस्प्लोसियन से पहले।
जुआन

5

पांच साल बाद रिएक्ट हुक की शुरुआत के साथ उपयोग कॉन्टेक्स्ट हुक के साथ इसे करने का बहुत अधिक सुरुचिपूर्ण तरीका है।

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

import React, { useState, useContext } from "react";
import ReactDOM from "react-dom";
import styles from "./styles.css";

// Create context container in a global scope so it can be visible by every component
const ContextContainer = React.createContext(null);

const initialAppState = {
  selected: "Nothing"
};

function App() {
  // The app has a state variable and update handler
  const [appState, updateAppState] = useState(initialAppState);

  return (
    <div>
      <h1>Passing state between components</h1>

      {/* 
          This is a context provider. We wrap in it any children that might want to access
          App's variables.
          In 'value' you can pass as many objects, functions as you want. 
           We wanna share appState and its handler with child components,           
       */}
      <ContextContainer.Provider value={{ appState, updateAppState }}>
        {/* Here we load some child components */}
        <Book title="GoT" price="10" />
        <DebugNotice />
      </ContextContainer.Provider>
    </div>
  );
}

// Child component Book
function Book(props) {
  // Inside the child component you can import whatever the context provider allows.
  // Earlier we passed value={{ appState, updateAppState }}
  // In this child we need the appState and the update handler
  const { appState, updateAppState } = useContext(ContextContainer);

  function handleCommentChange(e) {
    //Here on button click we call updateAppState as we would normally do in the App
    // It adds/updates comment property with input value to the appState
    updateAppState({ ...appState, comment: e.target.value });
  }

  return (
    <div className="book">
      <h2>{props.title}</h2>
      <p>${props.price}</p>
      <input
        type="text"
        //Controlled Component. Value is reverse vound the value of the variable in state
        value={appState.comment}
        onChange={handleCommentChange}
      />
      <br />
      <button
        type="button"
        // Here on button click we call updateAppState as we would normally do in the app
        onClick={() => updateAppState({ ...appState, selected: props.title })}
      >
        Select This Book
      </button>
    </div>
  );
}

// Just another child component
function DebugNotice() {
  // Inside the child component you can import whatever the context provider allows.
  // Earlier we passed value={{ appState, updateAppState }}
  // but in this child we only need the appState to display its value
  const { appState } = useContext(ContextContainer);

  /* Here we pretty print the current state of the appState  */
  return (
    <div className="state">
      <h2>appState</h2>
      <pre>{JSON.stringify(appState, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.body;
ReactDOM.render(<App />, rootElement);

आप इस उदाहरण को कोड सैंडबॉक्स संपादक में चला सकते हैं।

पासिंग-स्टेट-विद संदर्भ को संपादित करें


2

मुझे आश्चर्य है कि जिस समय मैं लिख रहा हूं उस समय एक सीधा मुहावरेदार प्रतिक्रिया समाधान के साथ कोई जवाब नहीं है। तो यहाँ एक है (आकार और दूसरों की जटिलता की तुलना करें):

class P extends React.Component {
    state = { foo : "" };

    render(){
        const { foo } = this.state;

        return (
            <div>
                <C1 value={ foo } onChange={ x => this.setState({ foo : x })} />
                <C2 value={ foo } />
            </div>
        )
    }
}

const C1 = ({ value, onChange }) => (
    <input type="text"
           value={ value }
           onChange={ e => onChange( e.target.value ) } />
);

const C2 = ({ value }) => (
    <div>Reacting on value change: { value }</div>
);

मैं बाल तत्व से मूल तत्व की स्थिति निर्धारित कर रहा हूं। यह प्रतिक्रिया के डिजाइन सिद्धांत को धोखा देता है: एकल-दिशा डेटा प्रवाह।

किसी भी नियंत्रितinput (प्रतिक्रिया में रूपों के साथ काम करने का मुहावरेदार) अपने onChangeकॉलबैक में मूल स्थिति को अपडेट करता है और फिर भी कुछ भी धोखा नहीं देता है।

उदाहरण के लिए, C1 घटक को ध्यान से देखें। क्या आप इस तरह से कोई महत्वपूर्ण अंतर देखते हैं कि कैसे C1और अंतर्निहित inputघटक राज्य परिवर्तनों को संभालते हैं? आपको नहीं करना चाहिए, क्योंकि कोई भी नहीं है। राज्य को ऊपर उठाना और मूल्य / onChange जोड़े को पारित करना कच्चे प्रतिक्रिया के लिए मुहावरेदार है। रेफरी का उपयोग नहीं, जैसा कि कुछ उत्तर बताते हैं।


1
आप किस संस्करण का उपयोग कर रहे हैं? मुझे प्रायोगिक श्रेणी की संपत्ति के मुद्दे मिल रहे हैं और फू को परिभाषित नहीं किया गया है।
आइजैक पाक

यह प्रतिक्रिया के एक संस्करण के बारे में नहीं था। घटक का कोड गलत था। इसे तय किया, अब प्रयास करें।
गैपरटॉन

जाहिर है, आपको राज्य सदस्य को निकालना होगा this.state, रिटर्न रेंडर में गायब था, और कई घटकों को div या कुछ में लपेटा जाना चाहिए। पता नहीं कैसे मैंने याद किया कि जब मैंने मूल उत्तर लिखा था। संपादन की गलती रही होगी।
गैपर्टन

1
मुझे यह समाधान पसंद है। यदि कोई इसके साथ छेड़छाड़ करना चाहता है, तो यहां आपके लिए एक सैंडबॉक्स है।
इसहाक पाक

2

एक उदाहरण के साथ अधिक हालिया उत्तर, जो उपयोग करता है React.useState

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

जब राज्य मूल घटक में होता है, तो बच्चा इसे बदल सकता है यदि माता-पिता बच्चे valueऔर onChangeहैंडलर को प्रॉप्स में देते हैं (कभी-कभी इसे मूल्य लिंक या राज्य लिंक पैटर्न कहा जाता है )। यहाँ है कि आप इसे हुक के साथ कैसे करेंगे:


function Parent() {
    var [state, setState] = React.useState('initial input value');
    return <>
        <Child1 value={state} onChange={(v) => setState(v)} />
        <Child2 value={state}>
    </>
}

function Child1(props) {
    return <input
        value={props.value}
        onChange={e => props.onChange(e.target.value)}
    />
}

function Child2(props) {
    return <p>Content of the state {props.value}</p>
}

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

राज्य लिंक पैटर्न और कोई भी माता-पिता पुन: रेंडर करना आसान नहीं है, जैसे कि थ्री पार्टी लाइब्रेरी का उपयोग करना, जैसे हुकस्ट्रेट - React.useStateआपके द्वारा एक सहित विभिन्न प्रकार के उपयोग के मामलों को कवर करने के लिए सुपरचार्ज्ड । (अस्वीकरण: मैं परियोजना का एक लेखक हूं)।

यहाँ है कि यह हुकस्टेट के साथ कैसा लगेगा। Child1इनपुट को बदल देगा, Child2उस पर प्रतिक्रिया देगा। Parentराज्य को धारण करेगा, लेकिन राज्य परिवर्तन पर केवल Child1और फिर से रेंडर नहीं Child2करेगा।

import { useStateLink } from '@hookstate/core';

function Parent() {
    var state = useStateLink('initial input value');
    return <>
        <Child1 state={state} />
        <Child2 state={state}>
    </>
}

function Child1(props) {
    // to avoid parent re-render use local state,
    // could use `props.state` instead of `state` below instead
    var state = useStateLink(props.state)
    return <input
        value={state.get()}
        onChange={e => state.set(e.target.value)}
    />
}

function Child2(props) {
    // to avoid parent re-render use local state,
    // could use `props.state` instead of `state` below instead
    var state = useStateLink(props.state)
    return <p>Content of the state {state.get()}</p>
}

पुनश्च: ऐसे कई और उदाहरण हैं जो समान रूप से और अधिक जटिल परिदृश्यों को कवर करते हैं, जिसमें गहरी नेस्टेड डेटा, राज्य सत्यापन, setStateहुक के साथ वैश्विक स्थिति आदि शामिल हैं। ऑनलाइन पूर्ण नमूना आवेदन भी है , जो हुकस्टेट और तकनीक का उपयोग करता है।


1

आपको Redux और ReactRedux लाइब्रेरी सीखनी चाहिए। यह आपके राज्यों और प्रॉप्स को एक स्टोर में संरचना देगा और आप उन्हें बाद में अपने घटकों में एक्सेस कर सकते हैं।


1

React> = 16.3 के साथ, आप अपने माता-पिता से बच्चे के डोम तक पहुंच प्राप्त करने के लिए रेफ और फॉरवर्ड रीफ का उपयोग कर सकते हैं। अब रेफरी के पुराने तरीके का उपयोग न करें।
यहाँ आपके मामले का उपयोग कर उदाहरण दिया गया है:

import React, { Component } from 'react';

export default class P extends React.Component {
   constructor (props) {
      super(props)
      this.state = {data: 'test' }
      this.onUpdate = this.onUpdate.bind(this)
      this.ref = React.createRef();
   }

   onUpdate(data) {
      this.setState({data : this.ref.current.value}) 
   }

   render () {
      return (
        <div>
           <C1 ref={this.ref} onUpdate={this.onUpdate}/>
           <C2 data={this.state.data}/>
        </div>
      )
   }
}

const C1 = React.forwardRef((props, ref) => (
    <div>
        <input type='text' ref={ref} onChange={props.onUpdate} />
    </div>
));

class C2 extends React.Component {
    render () {
       return <div>C2 reacts : {this.props.data}</div>
    }
}

देखें Refs और ForwardRef refs और forwardRef के बारे में विस्तृत जानकारी के लिए।


0
  1. सही बात यह है कि माता-पिता के घटक में राज्य होना चाहिए, रेफ से बचने के लिए और क्या नहीं
  2. एक मुद्दा यह है कि किसी क्षेत्र में लिखते समय सभी बच्चों को लगातार अपडेट करने से बचें
  3. इसलिए, प्रत्येक बच्चे को एक घटक होना चाहिए (जैसा कि एक PureComponent नहीं) और लागू करें shouldComponentUpdate(nextProps, nextState)
  4. इस तरह, जब एक फॉर्म फ़ील्ड में टाइप किया जाता है, केवल उस फ़ील्ड को अपडेट किया जाता है

का उपयोग करता है नीचे दिए गए कोड @boundसे एनोटेशन ES.Next babel-plugin-transform-decorators-legacy की BabelJS 6 और वर्ग-गुण (एनोटेशन बाँध के समान सदस्य कार्यों पर यह मान सेट):

/*
© 2017-present Harald Rudell <harald.rudell@gmail.com> (http://www.haraldrudell.com)
All rights reserved.
*/
import React, {Component} from 'react'
import {bound} from 'class-bind'

const m = 'Form'

export default class Parent extends Component {
  state = {one: 'One', two: 'Two'}

  @bound submit(e) {
    e.preventDefault()
    const values = {...this.state}
    console.log(`${m}.submit:`, values)
  }

  @bound fieldUpdate({name, value}) {
    this.setState({[name]: value})
  }

  render() {
    console.log(`${m}.render`)
    const {state, fieldUpdate, submit} = this
    const p = {fieldUpdate}
    return (
      <form onSubmit={submit}> {/* loop removed for clarity */}
        <Child name='one' value={state.one} {...p} />
        <Child name='two' value={state.two} {...p} />
        <input type="submit" />
      </form>
    )
  }
}

class Child extends Component {
  value = this.props.value

  @bound update(e) {
    const {value} = e.target
    const {name, fieldUpdate} = this.props
    fieldUpdate({name, value})
  }

  shouldComponentUpdate(nextProps) {
    const {value} = nextProps
    const doRender = value !== this.value
    if (doRender) this.value = value
    return doRender
  }

  render() {
    console.log(`Child${this.props.name}.render`)
    const {value} = this.props
    const p = {value}
    return <input {...p} onChange={this.update} />
  }
}

0

माता-पिता से बच्चे और इसके विपरीत डेटा पास करने की अवधारणा को समझाया गया है।

import React, { Component } from "react";
import ReactDOM from "react-dom";

// taken refrence from https://gist.github.com/sebkouba/a5ac75153ef8d8827b98

//example to show how to send value between parent and child

//  props is the data which is passed to the child component from the parent component

class Parent extends Component {
  constructor(props) {
    super(props);

    this.state = {
      fieldVal: ""
    };
  }

  onUpdateParent = val => {
    this.setState({
      fieldVal: val
    });
  };

  render() {
    return (
      // To achieve the child-parent communication, we can send a function
      // as a Prop to the child component. This function should do whatever
      // it needs to in the component e.g change the state of some property.
      //we are passing the function onUpdateParent to the child
      <div>
        <h2>Parent</h2>
        Value in Parent Component State: {this.state.fieldVal}
        <br />
        <Child onUpdate={this.onUpdateParent} />
        <br />
        <OtherChild passedVal={this.state.fieldVal} />
      </div>
    );
  }
}

class Child extends Component {
  constructor(props) {
    super(props);

    this.state = {
      fieldValChild: ""
    };
  }

  updateValues = e => {
    console.log(e.target.value);
    this.props.onUpdate(e.target.value);
    // onUpdateParent would be passed here and would result
    // into onUpdateParent(e.target.value) as it will replace this.props.onUpdate
    //with itself.
    this.setState({ fieldValChild: e.target.value });
  };

  render() {
    return (
      <div>
        <h4>Child</h4>
        <input
          type="text"
          placeholder="type here"
          onChange={this.updateValues}
          value={this.state.fieldVal}
        />
      </div>
    );
  }
}

class OtherChild extends Component {
  render() {
    return (
      <div>
        <h4>OtherChild</h4>
        Value in OtherChild Props: {this.props.passedVal}
        <h5>
          the child can directly get the passed value from parent by this.props{" "}
        </h5>
      </div>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById("root"));


1
मैं आपको सुझाव दूंगा कि आप अपने उत्तर में दिए गए विवरण को जोड़ने के लिए एक टिप्पणी के रूप में पिछले उत्तर के मालिक को सूचित करें। शिष्टाचार के लिए अपना नाम वापस लेने के बाद।
थॉमस इस्सो

@ThomasEaso मैं उसे यहाँ नहीं ढूँढ सकता, मैंने इसकी जाँच की। क्या कोई अन्य सुझाव हैं
अक्षय

उसके आइकन के बाईं ओर "संपादित करें" बटन पर क्लिक करें और अपने उत्तर को संशोधित करें और सबमिट करें। यह एक मॉडरेटर के पास जाएगा और वे आपकी मूल्यवान टिप्पणियों के लिए ज़रूरतमंदों को करेंगे।
थॉमस इस्सो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.