ReactJS संचार करने वाले दो घटक


321

मैं अभी रिएक्टजेएस के साथ शुरू हुआ हूं और एक समस्या पर थोड़ा अटक गया हूं जो मेरे पास है।

मेरा आवेदन अनिवार्य रूप से लेआउट बदलने के लिए फिल्टर और एक बटन के साथ एक सूची है। फिलहाल मैं तीन घटकों का उपयोग कर रहा: <list />, < Filters />और <TopBar />, अब स्पष्ट रूप से जब मैं सेटिंग में बदलाव में < Filters />मैं में कुछ विधि ट्रिगर करना चाहते हैं<list /> मेरे विचार अद्यतन करने के लिए।

मैं उन 3 घटकों को एक दूसरे के साथ कैसे बातचीत कर सकता हूं, या क्या मुझे किसी प्रकार के वैश्विक डेटा मॉडल की आवश्यकता है जहां मैं सिर्फ बदलाव कर सकता हूं?


सभी तीन भाई घटक हैं या एक दूसरे के भीतर है?
pgreen2

वे सभी तीन घटक हैं, मैंने पहले ही अपने आवेदन को फिर से व्यवस्थित कर लिया है ताकि वे अब एक ही माता-पिता हों जो उन्हें डेटा प्रदान कर सकें।
woutr_be

4
यह वह जगह है जहाँ आप फ्लक्स या पबसूब पैटर्न का उपयोग कर सकते हैं। डॉक्स के आधार पर प्रतिक्रिया डॉक्स में वे कुछ अस्पष्ट वाक्य छोड़ते हैं: "दो घटकों के बीच संचार के लिए जिनके पास माता-पिता-बच्चे का रिश्ता नहीं है, आप अपनी खुद की वैश्विक घटना प्रणाली स्थापित कर सकते हैं।" facebook.github.io/react/tips/…
BingeBoy

@BingeBoy सही है फ्लक्स रिएक्टज एप्लिकेशन लिखने का एक शानदार तरीका है, जो कई घटकों के डेटा प्रवाह, डेटा साझा करने की समस्या को संभाल सकता है।
अंकित पटियाल

4
आप फ्लक्स या Redux में पाने के लिए नहीं करना चाहते हैं, इस इस विषय पर एक भयानक लेख है andrewhfarmer.com/component-communication
garajo

जवाबों:


318

सबसे अच्छा तरीका इस बात पर निर्भर करेगा कि आप उन घटकों की व्यवस्था कैसे करते हैं। कुछ उदाहरण परिदृश्य जो अभी दिमाग में आते हैं:

  1. <Filters /> का एक बच्चा घटक है <List />
  2. दोनों <Filters />और <List />एक माता पिता के घटक के बच्चे हैं
  3. <Filters />और <List />पूरी तरह से अलग जड़ घटकों में रहते हैं।

ऐसे अन्य परिदृश्य हो सकते हैं जिनके बारे में मैं नहीं सोच रहा हूं। अगर तुम्हारा इन के भीतर फिट नहीं है, तो मुझे बताएं। यहाँ कुछ बहुत ही मोटे उदाहरण दिए गए हैं कि मैं पहले दो परिदृश्यों को कैसे संभाल रहा हूँ:

दृष्टांत 1

आप से कोई हैंडलर गुजारें सकता <List />करने के लिए <Filters />है, जो तब पर कहा जा सकता है onChangeवर्तमान मूल्य के साथ सूची फ़िल्टर करने की घटना।

# 1 → के लिए JSFiddle

/** @jsx React.DOM */

var Filters = React.createClass({
  handleFilterChange: function() {
    var value = this.refs.filterInput.getDOMNode().value;
    this.props.updateFilter(value);
  },
  render: function() {
    return <input type="text" ref="filterInput" onChange={this.handleFilterChange} placeholder="Filter" />;
  }
});

var List = React.createClass({
  getInitialState: function() {
    return {
      listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
      nameFilter: ''
    };
  },
  handleFilterUpdate: function(filterValue) {
    this.setState({
      nameFilter: filterValue
    });
  },
  render: function() {
    var displayedItems = this.state.listItems.filter(function(item) {
      var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
      return (match !== -1);
    }.bind(this));

    var content;
    if (displayedItems.length > 0) {
      var items = displayedItems.map(function(item) {
        return <li>{item}</li>;
      });
      content = <ul>{items}</ul>
    } else {
      content = <p>No items matching this filter</p>;
    }

    return (
      <div>
        <Filters updateFilter={this.handleFilterUpdate} />
        <h4>Results</h4>
        {content}
      </div>
    );
  }
});

React.renderComponent(<List />, document.body);

परिदृश्य # 2

परिदृश्य # 1 के समान, लेकिन मूल घटक हैंडलर फ़ंक्शन को <Filters />पास करने वाला एक होगा, और फ़िल्टर की गई सूची को पास करेगा <List />। मुझे यह तरीका बेहतर लगता है क्योंकि इसमें से डिकॉय <List />होता है <Filters />

# 2 → के लिए JSFiddle

/** @jsx React.DOM */

var Filters = React.createClass({
  handleFilterChange: function() {
    var value = this.refs.filterInput.getDOMNode().value;
    this.props.updateFilter(value);
  },
  render: function() {
    return <input type="text" ref="filterInput" onChange={this.handleFilterChange} placeholder="Filter" />;
  }
});

var List = React.createClass({
  render: function() {
    var content;
    if (this.props.items.length > 0) {
      var items = this.props.items.map(function(item) {
        return <li>{item}</li>;
      });
      content = <ul>{items}</ul>
    } else {
      content = <p>No items matching this filter</p>;
    }
    return (
      <div className="results">
        <h4>Results</h4>
        {content}
      </div>
    );
  }
});

var ListContainer = React.createClass({
  getInitialState: function() {
    return {
      listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
      nameFilter: ''
    };
  },
  handleFilterUpdate: function(filterValue) {
    this.setState({
      nameFilter: filterValue
    });
  },
  render: function() {
    var displayedItems = this.state.listItems.filter(function(item) {
      var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
      return (match !== -1);
    }.bind(this));

    return (
      <div>
        <Filters updateFilter={this.handleFilterUpdate} />
        <List items={displayedItems} />
      </div>
    );
  }
});

React.renderComponent(<ListContainer />, document.body);

परिदृश्य # 3

जब घटक किसी भी तरह के अभिभावक-बच्चे के रिश्ते के बीच संवाद नहीं कर सकते हैं, तो प्रलेखन एक वैश्विक घटना प्रणाली स्थापित करने की सिफारिश करता है


6
के रूप में एक समारोह: # 2 के साथ अच्छी बात यह है कि वे केवल एक माता पिता कौन प्रत्येक घटक के लिए एक आधार के गुजरता है पर भरोसा है updateFilterकरने के लिए <Filters />और के रूप में एक सरणी itemsके लिए <List />। आप उन बच्चों के घटकों का उपयोग अन्य माता-पिता के साथ अलग-अलग व्यवहारों में कर सकते हैं, या तो एक साथ या एकल। उदाहरण के लिए, यदि आप एक डायनामिक सूची प्रदर्शित करना चाहते हैं, लेकिन फ़िल्टर करने की आवश्यकता नहीं है।
माइकल लॉक्रिक्स

2
@woutr_be निश्चित नहीं है कि यह आपकी आवश्यकता में फिट होगा, लेकिन जब कुछ समय पहले इसी तरह की स्थिति में, हमने बच्चे और माता-पिता के घटकों के बीच संवाद करने के लिए दो कार्यों का उपयोग किया था: - ListenTo: function (eventName, eventCameback) {$ window.document) .bind (eventName, eventCallback);} ट्रिगरईवेंट: फ़ंक्शन (EventName, params) {$ .event.trigger (eventName, params);} आशा है कि यह मदद करता है; (सॉरी इसे बेहतर प्रारूपित नहीं किया जा सका)
5122014009

29
परिदृश्य 3 के लिए, क्या कोई अनुशंसित दृष्टिकोण है? किसी भी डॉक्स या उदाहरण पर कस्टम सिंथेटिक घटनाओं को उत्पन्न करके? मुझे मुख्य डॉक्स में कुछ भी नहीं मिला है।
पावरे

1
परिदृश्य # 2 बनाता है भावना का एक बहुत ... जब तक आप डिजाइन ख़तरे में डालना (यदि केवल, लेआउट) है - तो आप एक EventHub / पबसब के लिए आवश्यकता का एहसास।
कोड़ी

4
परिदृश्य # 3 लिंक मृत है और एक असंबंधित रिएक्ट डॉक्स पृष्ठ पर पुनर्निर्देशित करता है।
21

170

घटकों को संवाद करने के कई तरीके हैं। कुछ आपके usecase के अनुकूल हो सकते हैं। यहाँ कुछ लोगों की सूची दी गई है जिन्हें मैंने जाना है।

प्रतिक्रिया

माता-पिता / बाल प्रत्यक्ष संचार

const Child = ({fromChildToParentCallback}) => (
  <div onClick={() => fromChildToParentCallback(42)}>
    Click me
  </div>
);

class Parent extends React.Component {
  receiveChildValue = (value) => {
    console.log("Parent received value from child: " + value); // value is 42
  };
  render() {
    return (
      <Child fromChildToParentCallback={this.receiveChildValue}/>
    )
  }
}

यहां बाल घटक माता-पिता द्वारा प्रदान किए गए कॉलबैक को एक मूल्य के साथ कॉल करेगा, और माता-पिता माता-पिता में बच्चों द्वारा प्रदान किए गए मूल्य को प्राप्त करने में सक्षम होंगे।

यदि आप अपने ऐप के एक फीचर / पेज का निर्माण करते हैं, तो कॉलबैक / स्टेट (जिसे भी कहा जाता है ) containerया smart componentसभी चाइल्ड को स्टेटलेस होने के लिए सिंगल पेरेंट का प्रबंध करना बेहतर होता है , केवल पेरेंट्स को चीजों की रिपोर्टिंग करना। इस तरह आप आसानी से किसी भी बच्चे को माता-पिता की स्थिति को "साझा" कर सकते हैं, जिसे इसकी आवश्यकता है।


प्रसंग

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

अब तक, संदर्भ एक प्रायोगिक विशेषता थी, लेकिन एक नया एपीआई प्रतिक्रिया 16.3 में उपलब्ध है।

const AppContext = React.createContext(null)

class App extends React.Component {
  render() {
    return (
      <AppContext.Provider value={{language: "en",userId: 42}}>
        <div>
          ...
          <SomeDeeplyNestedComponent/>
          ...
        </div>
      </AppContext.Provider>
    )
  }
};

const SomeDeeplyNestedComponent = () => (
  <AppContext.Consumer>
    {({language}) => <div>App language is currently {language}</div>}
  </AppContext.Consumer>
);

उपभोक्ता का उपयोग कर रहा है रेंडर प्रोप / चिल्ड्रेन फंक्शन पैटर्न

अधिक जानकारी के लिए इस ब्लॉग पोस्ट की जाँच करें ।

16.3 प्रतिक्रिया से पहले, मैं प्रतिक्रिया-प्रसारण का उपयोग करने की सलाह दूंगा जो काफी समान एपीआई की पेशकश करता है, और पूर्व संदर्भ एपीआई का उपयोग करता है।


पोर्टल

एक पोर्टल का उपयोग तब करें जब आप सामान्य माता-पिता / बच्चे की तरह साधारण कार्यों के साथ संवाद करने के लिए 2 घटकों को एक साथ रखना चाहते हैं, लेकिन आप नहीं चाहते हैं कि इन 2 घटकों को DOM में माता-पिता / बच्चे का रिश्ता हो, क्योंकि दृश्य / सीएसएस की कमी का तात्पर्य है (जैसे z- इंडेक्स, अपारदर्शिता ...)।

इस मामले में आप "पोर्टल" का उपयोग कर सकते हैं। पोर्टल्स का उपयोग करके अलग-अलग प्रतिक्रिया पुस्तकालय हैं , आमतौर पर मॉडल , पॉपअप, टूलटिप्स के लिए उपयोग किया जाता है ...

निम्नलिखित को धयान मे रखते हुए:

<div className="a">
    a content
    <Portal target="body">
        <div className="b">
            b content
        </div>
    </Portal>
</div>

अंदर प्रस्तुत किए जाने पर निम्नलिखित DOM उत्पन्न कर सकता है reactAppContainer:

<body>
    <div id="reactAppContainer">
        <div className="a">
             a content
        </div>
    </div>
    <div className="b">
         b content
    </div>
</body>

अधिक जानकारी यहाँ


स्लॉट्स

आप कहीं एक स्लॉट को परिभाषित करते हैं, और फिर आप अपने रेंडर ट्री के किसी अन्य स्थान से स्लॉट को भरते हैं।

import { Slot, Fill } from 'react-slot-fill';

const Toolbar = (props) =>
  <div>
    <Slot name="ToolbarContent" />
  </div>

export default Toolbar;

export const FillToolbar = ({children}) =>
  <Fill name="ToolbarContent">
    {children}
  </Fill>

यह कुछ हद तक पोर्टल्स के समान है सिवाय भरे हुए कंटेंट को आपके द्वारा परिभाषित एक स्लॉट में प्रस्तुत किया जाएगा, जबकि पोर्टल्स आम तौर पर एक नया डोम नोड (अक्सर डॉक्यूमेंट के एक बच्चे) प्रस्तुत करते हैं।

प्रतिक्रिया-स्लॉट-भरण पुस्तकालय की जाँच करें


घटना बस

जैसा कि प्रतिक्रिया दस्तावेज में कहा गया है :

दो घटकों के बीच संचार के लिए, जिनके माता-पिता-बच्चे के संबंध नहीं हैं, आप अपना स्वयं का वैश्विक ईवेंट सिस्टम सेट कर सकते हैं। जब आप कोई ईवेंट प्राप्त करते हैं, तो कंपोनेंटमाउंट (), और घटकविलीयूएनमाउंट (), और कॉल सेटस्टेट () में सदस्यता समाप्त करें।

एक इवेंट बस को सेटअप करने के लिए आप कई चीजों का उपयोग कर सकते हैं। आप केवल श्रोताओं की एक सरणी बना सकते हैं, और ईवेंट प्रकाशित होने पर, सभी श्रोता ईवेंट प्राप्त करेंगे। या आप EventEmitter या PostalJs जैसी किसी चीज़ का उपयोग कर सकते हैं


फ्लक्स

फ्लक्स मूल रूप से एक इवेंट बस है, सिवाय इवेंट रिसीवर्स स्टोर के। यह मूल घटना बस प्रणाली के समान है सिवाय राज्य को प्रतिक्रिया के बाहर प्रबंधित किया जाता है

ओरिजिनल फ्लक्स का कार्यान्वयन इवेंट-सोर्सिंग को हैक करने के तरीके की तरह करता है।

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

Egghead का Redux वीडियो ट्यूटोरियल वास्तव में अच्छा है और बताता है कि यह आंतरिक रूप से कैसे काम करता है (यह वास्तव में सरल है)।


कर्सर

Cloors ClojureScript / Om से आ रहे हैं और व्यापक रूप से React प्रोजेक्ट्स में उपयोग किए जाते हैं। वे प्रतिक्रिया के बाहर राज्य का प्रबंधन करने की अनुमति देते हैं, और घटक पेड़ के बारे में कुछ भी जानने की आवश्यकता के बिना कई घटकों को राज्य के एक ही हिस्से में पढ़ने / लिखने की अनुमति देते हैं।

कई कार्यान्वयन मौजूद हैं, जिनमें ImmutableJS , प्रतिक्रिया-कर्सर और सर्वज्ञ शामिल हैं

संपादन २०१६ : ऐसा लगता है कि लोग सहमत हैं कि शाप देने वाले छोटे ऐप्स के लिए ठीक काम करते हैं, लेकिन यह जटिल ऐप्स पर अच्छा नहीं लगता। ओम नेक्सस के पास अब कोई शाप नहीं है (जबकि यह ओम है जिसने शुरू में अवधारणा पेश की थी)


एल्म वास्तुकला

एल्म वास्तुकला द्वारा इस्तेमाल किया जा करने का प्रस्ताव एक वास्तुकला है एल्म भाषा । भले ही एल्म रिएक्टजेएस नहीं है, फिर भी रिएक्ट में एल्म आर्किटेक्चर किया जा सकता है।

Redux के लेखक डैन अब्रामोव ने रिएक्ट का उपयोग करके एल्म वास्तुकला का कार्यान्वयन किया ।

Redux और Elm दोनों ही वास्तव में बहुत अच्छे हैं और फ्रंटएंड पर इवेंट-सोर्सिंग कॉन्सेप्ट को सशक्त बनाने के लिए हैं, दोनों समय-यात्रा डिबगिंग, पूर्ववत / रीडो, रीप्ले की अनुमति देते हैं ...

Redux और Elm के बीच मुख्य अंतर यह है कि एल्म राज्य प्रबंधन के बारे में बहुत अधिक सख्त हैं। एल्म में आपके पास स्थानीय घटक स्थिति या माउंट / अनमाउंट हुक नहीं हो सकते हैं और सभी डोम परिवर्तन को वैश्विक राज्य परिवर्तनों द्वारा ट्रिगर किया जाना चाहिए। एल्म आर्किटेक्चर एक स्केलेबल दृष्टिकोण का प्रस्ताव करता है जो एक अपरिवर्तनीय वस्तु के अंदर सभी राज्य को संभालने की अनुमति देता है , जबकि Redux एक दृष्टिकोण का प्रस्ताव करता है जो आपको एक अपरिवर्तनीय वस्तु में राज्य के MOST को संभालने के लिए आमंत्रित करता है ।

जबकि एल्म का वैचारिक मॉडल बहुत ही सुंदर है और वास्तुकला बड़े ऐप्स पर अच्छी तरह से स्केल करने की अनुमति देती है, यह मुश्किल हो सकता है या सरल कार्यों को प्राप्त करने के लिए अधिक बॉयलरप्लेट को शामिल कर सकता है जैसे कि बढ़ते के बाद किसी इनपुट पर ध्यान देना, या किसी मौजूदा लाइब्रेरी के साथ एकीकरण करना। एक अनिवार्य इंटरफ़ेस (यानी JQuery प्लगइन) के साथ। संबंधित मुद्दा

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


एफआरपी

RxJS, BaconJS या केफिर जैसे पुस्तकालयों का उपयोग घटकों के बीच संचार को संभालने के लिए FRP स्ट्रीम बनाने के लिए किया जा सकता है।

आप Rx-React उदाहरण के लिए प्रयास कर सकते हैं

मुझे लगता है कि ईएलएम भाषा संकेतों के साथ जो प्रदान करती है उसका उपयोग करने के लिए इन कामों का उपयोग काफी समान है

CycleJS फ्रेमवर्क ReactJS का उपयोग नहीं करता है, लेकिन vdom का उपयोग करता है । यह एल्म वास्तुकला के साथ बहुत सारी समानताएं साझा करता है (लेकिन वास्तविक जीवन में इसका उपयोग करना अधिक आसान है क्योंकि यह वुड हुक की अनुमति देता है) और यह फ़ंक्शन के बजाय बड़े पैमाने पर आरएक्सजे का उपयोग करता है, और यदि आप एफआरपी का उपयोग करना चाहते हैं तो प्रेरणा का एक अच्छा स्रोत हो सकता है। प्रतिक्रिया होती है। CycleJs Egghead वीडियो यह समझने में अच्छा है कि यह कैसे काम करता है।


सीएसपी

CSP (कम्यूनिकेटिंग सेक्शनल प्रोसेस) वर्तमान में लोकप्रिय हैं (ज्यादातर गो / गोरआउट और core.async / ClojureScript के कारण) लेकिन आप इन्हें JS-CSP के साथ जावास्क्रिप्ट में भी उपयोग कर सकते हैं ।

जेम्स लॉन्ग ने एक वीडियो किया है जिसमें बताया गया है कि इसे कैसे रिएक्ट के साथ इस्तेमाल किया जा सकता है।

गाथा

एक गाथा एक बैकएंड अवधारणा है जो DDD / EventSourcing / CQRS दुनिया से आती है, जिसे "प्रक्रिया प्रबंधक" भी कहा जाता है। इसे रेडक्स-सागा द्वारा लोकप्रिय बनाया जा रहा है प्रोजेक्ट , ज्यादातर साइड-इफेक्ट्स (यानी एपीआई कॉल आदि) से निपटने के लिए Redux-thunk के प्रतिस्थापन के रूप में। ज्यादातर लोग वर्तमान में इसे केवल साइड-इफेक्ट्स के लिए सेवाएं मानते हैं, लेकिन यह वास्तव में डिकम्पलिंग घटकों के बारे में अधिक है।

यह एक पूरी तरह से नई संचार प्रणाली की तुलना में एक फ्लक्स आर्किटेक्चर (या रेडक्स) के लिए एक तारीफ है, क्योंकि गाथा अंत में फ्लक्स कार्यों का उत्सर्जन करती है। विचार यह है कि यदि आपके पास विजेट 1 और विजेट 2 हैं, और आप चाहते हैं कि उन्हें डिकॉय किया जाए, तो आप विजेट 1 पर विजेट 2 को लक्षित कर आग नहीं लगा सकते। इसलिए आप विजेट 1 को केवल फायर एक्शन बनाते हैं जो खुद को निशाना बनाते हैं, और गाथा एक "पृष्ठभूमि प्रक्रिया" है जो विजेट 1 क्रियाओं के लिए सुनता है, और विजेट 2 को लक्षित करने वाली क्रियाएं भेज सकता है। गाथा 2 विगेट्स के बीच युग्मन बिंदु है, लेकिन विजेट्स डिकूप्ड रहते हैं।

यदि आप रुचि रखते हैं तो मेरे उत्तर पर एक नज़र डालें


निष्कर्ष

यदि आप इन विभिन्न शैलियों का उपयोग करके उसी छोटे ऐप का एक उदाहरण देखना चाहते हैं, तो इस भंडार की शाखाओं की जांच करें ।

मुझे नहीं पता कि दीर्घकालिक में सबसे अच्छा विकल्प क्या है, लेकिन मुझे वास्तव में पसंद है कि फ्लक्स इवेंट-सोर्सिंग की तरह कैसे दिखता है।

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

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


2
बहुत बढ़िया जवाब!
अली गजनी

7

ठीक है, इसे करने के कुछ तरीके हैं, लेकिन मैं विशेष रूप से Redux का उपयोग करके स्टोर का उपयोग करने पर ध्यान केंद्रित करना चाहता हूं जो आपके जीवन को इन स्थितियों के लिए बहुत आसान बना देता है बजाय इसके कि आप इस मामले के लिए त्वरित समाधान दें, शुद्ध प्रतिक्रिया का उपयोग करने से गड़बड़ हो जाएगी। वास्तविक बड़ा आवेदन और घटकों के बीच संवाद स्थापित करने के रूप में कठिन और कठिन हो जाता है ...

तो Redux आपके लिए क्या करता है?

Redux आपके एप्लिकेशन में स्थानीय स्टोरेज की तरह है जिसका उपयोग तब भी किया जा सकता है जब आपको अपने एप्लिकेशन में विभिन्न स्थानों पर उपयोग किए जाने वाले डेटा की आवश्यकता हो ...

मूल रूप से, Redux का विचार मूल रूप से प्रवाह से आता है, लेकिन कुछ मूलभूत परिवर्तनों के साथ जिसमें केवल एक ही निर्माण करके सत्य का एक स्रोत होने की अवधारणा शामिल है ...

फ्लक्स और Redux के बीच कुछ अंतर देखने के लिए नीचे दिए गए ग्राफ को देखें ...

Redux और फ्लक्स

यदि आपके आवेदन को अवयवों के बीच संचार की आवश्यकता है, तो शुरू से ही अपने आवेदन में Redux लगाने पर विचार करें ...

Redux प्रलेखन से इन शब्दों को पढ़ना भी शुरू करने में मददगार हो सकता है:

चूंकि जावास्क्रिप्ट सिंगल-पेज अनुप्रयोगों के लिए आवश्यकताएं तेजी से जटिल हो गई हैं, हमारे कोड को पहले से कहीं अधिक राज्य का प्रबंधन करना चाहिए । इस राज्य में सर्वर प्रतिक्रियाएं और कैश्ड डेटा, साथ ही स्थानीय रूप से बनाए गए डेटा शामिल हो सकते हैं जो अभी तक सर्वर पर बरकरार नहीं हैं। UI स्थिति भी जटिलता में बढ़ रही है, क्योंकि हमें सक्रिय मार्गों, चयनित टैब, स्पिनर, पृष्ठ पर नियंत्रण और इतने पर प्रबंधन करने की आवश्यकता है।

इस बदलते राज्य का प्रबंधन कठिन है। यदि कोई मॉडल किसी अन्य मॉडल को अपडेट कर सकता है, तो एक दृश्य एक मॉडल को अपडेट कर सकता है, जो किसी अन्य मॉडल को अपडेट करता है, और यह बदले में, किसी अन्य दृश्य को अपडेट करने का कारण हो सकता है। कुछ बिंदु पर, आप अब यह नहीं समझते हैं कि आपके ऐप में क्या होता है क्योंकि आपने कब, क्यों और कैसे इसकी स्थिति पर नियंत्रण खो दिया है। जब एक प्रणाली अपारदर्शी और गैर-नियतात्मक होती है, तो बग को पुन: पेश करना या नई सुविधाओं को जोड़ना मुश्किल होता है।

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

इस जटिलता को संभालना मुश्किल है क्योंकि हम दो अवधारणाओं को मिला रहे हैं जो मानव मन के लिए बहुत कठिन हैं: उत्परिवर्तन और अतुल्यकालिकता। मैं उन्हें मेंटोस और कोक कहता हूं। दोनों अलगाव में महान हो सकते हैं, लेकिन एक साथ वे एक गड़बड़ पैदा करते हैं। लाइब्रेरी जैसी प्रतिक्रियाएं एसिंक्रोनसी और डायरेक्ट डोम हेरफेर दोनों को हटाकर दृश्य परत में इस समस्या को हल करने का प्रयास करती हैं। हालाँकि, आपके डेटा की स्थिति को प्रबंधित करना आपके लिए शेष है। यह वह जगह है जहाँ Redux प्रवेश करती है।

फ्लक्स, CQRS, और इवेंट सोर्सिंग के चरणों में अनुसरण करते हुए , Redux स्टेट्स म्यूटेशन को कैसे और कब अपडेट हो सकता है, इस पर कुछ प्रतिबंध लगाकर अनुमान लगाने का प्रयास करता है । ये प्रतिबंध Redux के तीन सिद्धांतों में परिलक्षित होते हैं।


Redux कैसे मदद कर सकता है? अगर मेरे पास a datepicker(एक घटक के रूप में) के लिए एक मोडल है और उस घटक को एक ही पृष्ठ पर रहने वाले कई घटकों से लोड किया जा सकता है, तो datepickerघटक को कैसे पता चलेगा कि कौन सा एक्शन Redux को भेजने के लिए है? यह समस्या का सार है, एक घटक में एक क्रिया को दूसरे से जोड़ना और किसी अन्य घटक से नहीं । (ध्यान में रखना datepickerखुद ही एक गहरी, गहन घटक है, जो कि स्वयं कंपोनेंट कंपोनेंट के भीतर है)
vsync

@vsync reudx को एक स्टैटिक वैल्यू के रूप में नहीं मानता है, Redux में वास्तव में ऑब्जेक्ट्स, सरणियाँ हो सकती हैं ... इसलिए आप उन्हें ऑब्जेक्ट या एरे के रूप में या अपने स्टोर में जो कुछ भी बचा सकते हैं, वह मैपडाइस्पैक्टटॉपटॉप्स हो सकता है और प्रत्येक ऑब्जेक्ट एरे में सेव हो सकता है जैसे: [{name: "picker1", value: "01/01/1970"}, {name: "picker2", value: "01/01/1980"}] और फिर माता-पिता में mapstatetoprops का उपयोग करें और इसे पास करें प्रत्येक घटक या जहाँ भी आप चाहते हैं, सुनिश्चित करें कि यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन कोड देखे बिना ... यदि वे अलग-अलग समूहों में हैं, तो आप अधिक विवरणों के साथ भी आपत्ति कर सकते हैं ... लेकिन यह सब आप कैसे करना चाहते हैं उन्हें ..
एलिरेज़ा

सवाल के बारे में नहीं है reduxऔर आप क्या स्टोर कर सकते हैं, लेकिन कैसे गहरी क्या यह को गति प्रदान करने की जरूरत है के लिए नीचे कार्रवाई पारित करने के लिए। एक गहरे घटक को कैसे पता चलता है कि वास्तव में क्या शुरू करने की आवश्यकता है? उदाहरण के बाद से मैंने एक सामान्य घटक दिया जो कि परिदृश्य के आधार पर एक विशिष्ट रेड्यूसर को ट्रिगर होना चाहिए, इसलिए यह किसी भी घटक के लिए डेटापिक मोडल का उपयोग करने के बाद से अलग-अलग रिड्यूसर हो सकता है।
vsync

5

इस तरह से मैंने इसे संभाला।
मान लें कि आपके पास एक <select> महीना के लिए और एक <select> दिन के लिए है । दिनों की संख्या चयनित महीने पर निर्भर करती है।

दोनों सूचियों का स्वामित्व एक तीसरे ऑब्जेक्ट, बाएं पैनल के पास है। दोनों <select> leftPanel के बच्चे भी हैं <div>
यह कॉलबैक और LeftPanel घटक में हैंडलर के साथ एक गेम है ।

इसका परीक्षण करने के लिए, बस कोड को दो अलग-अलग फ़ाइलों में कॉपी करें और index.html चलाएं । फिर एक महीने का चयन करें और देखें कि दिनों की संख्या कैसे बदलती है।

dates.js

    /** @jsx React.DOM */


    var monthsLength = [0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    var MONTHS_ARR = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

    var DayNumber = React.createClass({
        render: function() {
            return (
                <option value={this.props.dayNum}>{this.props.dayNum}</option>
            );
        }
    });

    var DaysList = React.createClass({
        getInitialState: function() {
            return {numOfDays: 30};
        },
        handleMonthUpdate: function(newMonthix) {
            this.state.numOfDays = monthsLength[newMonthix];
            console.log("Setting days to " + monthsLength[newMonthix] + " month = " + newMonthix);

            this.forceUpdate();
        },
        handleDaySelection: function(evt) {
            this.props.dateHandler(evt.target.value);
        },
        componentDidMount: function() {
            this.props.readyCallback(this.handleMonthUpdate)
        },
        render: function() {
            var dayNodes = [];
            for (i = 1; i <= this.state.numOfDays; i++) {
                dayNodes = dayNodes.concat([<DayNumber dayNum={i} />]);
            }
            return (
                <select id={this.props.id} onChange = {this.handleDaySelection}>
                    <option value="" disabled defaultValue>Day</option>
                        {dayNodes}
                </select>
                );
        }
    });

    var Month = React.createClass({
        render: function() {
            return (
                <option value={this.props.monthIx}>{this.props.month}</option>
            );
        }
    });

    var MonthsList = React.createClass({
        handleUpdate: function(evt) {
            console.log("Local handler:" + this.props.id + " VAL= " + evt.target.value);
            this.props.dateHandler(evt.target.value);

            return false;
        },
        render: function() {
            var monthIx = 0;

            var monthNodes = this.props.data.map(function (month) {
                monthIx++;
                return (
                    <Month month={month} monthIx={monthIx} />
                    );
            });

            return (
                <select id = {this.props.id} onChange = {this.handleUpdate}>
                    <option value="" disabled defaultValue>Month</option>
                        {monthNodes}
                </select>
                );
        }
    });

    var LeftPanel = React.createClass({
        dayRefresh: function(newMonth) {
            // Nothing - will be replaced
        },
        daysReady: function(refreshCallback) {
            console.log("Regisering days list");
        this.dayRefresh = refreshCallback;
        },
        handleMonthChange: function(monthIx) {
            console.log("New month");
            this.dayRefresh(monthIx);
        },
        handleDayChange: function(dayIx) {
            console.log("New DAY: " + dayIx);
        },
        render: function() {
            return(
                <div id="orderDetails">
                    <DaysList id="dayPicker" dateHandler={this.handleDayChange} readyCallback = {this.daysReady} />
                    <MonthsList data={MONTHS_ARR} id="monthPicker" dateHandler={this.handleMonthChange}  />
                </div>
            );
        }
    });



    React.renderComponent(
        <LeftPanel />,
        document.getElementById('leftPanel')
    );

और बाएँ पैनल घटक index.html चलाने के लिए HTML

<!DOCTYPE html>
<html>
<head>
    <title>Dates</title>

    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
    <script src="//fb.me/react-0.11.1.js"></script>
    <script src="//fb.me/JSXTransformer-0.11.1.js"></script>
</head>

    <style>

        #dayPicker {
            position: relative;
            top: 97px;
            left: 20px;
            width: 60px;
            height: 17px;
        }

        #monthPicker {
            position: relative;
            top: 97px;
            left: 22px;
            width: 95px;
            height: 17px;
        }

        select {
            font-size: 11px;
        }

    </style>


    <body>
        <div id="leftPanel">
        </div>

        <script type="text/jsx" src="dates.js"></script>

    </body>
</html>

अगर आप 80% उदाहरण कोड हटा सकते हैं और फिर भी अपनी बात रख सकते हैं, तो यह सबसे अच्छा होगा। इस थ्रेड के संदर्भ में सीएसएस दिखाते हुए यह अप्रासंगिक है
vsync

3

मैंने देखा कि प्रश्न पहले से ही उत्तर दिया गया है, लेकिन यदि आप अधिक विवरण सीखना चाहते हैं, तो घटकों के बीच संचार के कुल 3 मामले हैं :

  • केस 1: पैरेंट टू चाइल्ड कम्युनिकेशन
  • केस 2: चाइल्ड टू पैरेंट कम्युनिकेशन
  • केस 3: संचार से संबंधित घटक (किसी भी घटक के लिए कोई घटक) नहीं

1

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

के मामले में <Filters />और <TopBar />इसके बाद के संस्करण संबंध में से किसी की जरूरत नहीं है, एक साधारण वैश्विक emitter इस तरह इस्तेमाल किया जा सकता:

componentDidMount - घटना की सदस्यता लें

componentWillUnmount - घटना से सदस्यता समाप्त करें

React.js और EventSystem कोड

EventSystem.js

class EventSystem{

    constructor() {
        this.queue = {};
        this.maxNamespaceSize = 50;
    }

    publish(/** namespace **/ /** arguments **/) {
        if(arguments.length < 1) {
            throw "Invalid namespace to publish";
        }

        var namespace = arguments[0];
        var queue = this.queue[namespace];

        if (typeof queue === 'undefined' || queue.length < 1) {
            console.log('did not find queue for %s', namespace);
            return false;
        }

        var valueArgs = Array.prototype.slice.call(arguments);

        valueArgs.shift(); // remove namespace value from value args

        queue.forEach(function(callback) {
            callback.apply(null, valueArgs);
        });

        return true;
    }

    subscribe(/** namespace **/ /** callback **/) {
        const namespace = arguments[0];
        if(!namespace) throw "Invalid namespace";
        const callback = arguments[arguments.length - 1];
        if(typeof callback !== 'function') throw "Invalid callback method";

        if (typeof this.queue[namespace] === 'undefined') {
            this.queue[namespace] = [];
        }

        const queue = this.queue[namespace];
        if(queue.length === this.maxNamespaceSize) {
            console.warn('Shifting first element in queue: `%s` since it reached max namespace queue count : %d', namespace, this.maxNamespaceSize);
            queue.shift();
        }

        // Check if this callback already exists for this namespace
        for(var i = 0; i < queue.length; i++) {
            if(queue[i] === callback) {
                throw ("The exact same callback exists on this namespace: " + namespace);
            }
        }

        this.queue[namespace].push(callback);

        return [namespace, callback];
    }

    unsubscribe(/** array or topic, method **/) {
        let namespace;
        let callback;
        if(arguments.length === 1) {
            let arg = arguments[0];
            if(!arg || !Array.isArray(arg)) throw "Unsubscribe argument must be an array";
            namespace = arg[0];
            callback = arg[1];
        }
        else if(arguments.length === 2) {
            namespace = arguments[0];
            callback = arguments[1];
        }

        if(!namespace || typeof callback !== 'function') throw "Namespace must exist or callback must be a function";
        const queue = this.queue[namespace];
        if(queue) {
            for(var i = 0; i < queue.length; i++) {
                if(queue[i] === callback) {
                    queue.splice(i, 1); // only unique callbacks can be pushed to same namespace queue
                    return;
                }
            }
        }
    }

    setNamespaceSize(size) {
        if(!this.isNumber(size)) throw "Queue size must be a number";
        this.maxNamespaceSize = size;
        return true;
    }

    isNumber(n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    }

}

NotificationComponent.js

class NotificationComponent extends React.Component {

    getInitialState() {
        return {
            // optional. see alternative below
            subscriber: null
        };
    }

    errorHandler() {
        const topic = arguments[0];
        const label = arguments[1];
        console.log('Topic %s label %s', topic, label);
    }

    componentDidMount() {
        var subscriber = EventSystem.subscribe('error.http', this.errorHandler);
        this.state.subscriber = subscriber;
    }

    componentWillUnmount() {
        EventSystem.unsubscribe('error.http', this.errorHandler);

        // alternatively
        // EventSystem.unsubscribe(this.state.subscriber);
    }

    render() {

    }
}

0

ऐसी कोई संभावना नहीं है, भले ही वे अभिभावक - बाल संबंध न हों - और यह फ्लक्स है। वहाँ बहुत अच्छा है (मेरे लिए व्यक्तिगत रूप से) कि Alt.JS (Alt- कंटेनर के साथ) के लिए कार्यान्वयन।

उदाहरण के लिए आपके पास साइडबार हो सकता है जो घटक विवरणों में सेट किए गए पर निर्भर है। घटक साइडबार साइडबारएक्शंस और साइडबारस्टोर के साथ जुड़ा हुआ है, जबकि विवरण विवरणएक्टेशंस और विवरणस्टोर्स है।

आप तब AltContainer का उपयोग कर सकते हैं

<AltContainer stores={{
                    SidebarStore: SidebarStore
                }}>
                    <Sidebar/>
</AltContainer>

{this.props.content}

जो स्टोर रखेगा (अच्छी तरह से मैं "स्टोर" प्रोप के बजाय "स्टोर" का उपयोग कर सकता हूं)। अब, {this.props.content} मार्ग के आधार पर विवरणों को लागू किया जा सकता है। कहते हैं कि / विवरण हमें उस दृश्य पर पुनर्निर्देशित करता है। उदाहरण के लिए एक चेकबॉक्स होगा, जो साइडबार तत्व को X से Y में बदल देगा यदि इसे चेक किया जाएगा।

तकनीकी रूप से उनके बीच कोई संबंध नहीं है और बिना फ्लक्स के ऐसा करना मुश्किल होगा। लेकिन यह आसान नहीं है।

अब चलिए DetailsActions पर आते हैं। हम वहीं बनाएंगे

class SiteActions {
constructor() {
    this.generateActions(
        'setSiteComponentStore'
    );
}

setSiteComponent(value) {
    this.dispatch({value: value});
}
}

और विवरण

class SiteStore {
constructor() {
    this.siteComponents = {
        Prop: true
    };

    this.bindListeners({
        setSiteComponent: SidebarActions.COMPONENT_STATUS_CHANGED
    })
}

setSiteComponent(data) {
    this.siteComponents.Prop = data.value;
}
}

और अब, यह वह स्थान है जहां जादू शुरू होता है।

जैसा कि आप देख सकते हैं कि साइडबारएक्शन्स के लिए bindListener है ।ComponentStatusChanged जिसका उपयोग किया जाएगा, तो ifSiteComponent का उपयोग किया जाएगा।

अब साइडबार में

    componentStatusChanged(value){
    this.dispatch({value: value});
}

हमारे पास ऐसी बात है। यह उस वस्तु को कॉल पर भेज देगा। और यह कहा जाएगा कि अगर setSiteComponent इन स्टोर का उपयोग किया जाएगा (जो कि आप बटन ओ.टी. पर ऑनचेंज के दौरान घटक के लिए उपयोग कर सकते हैं जो भी हो)

अब साइडबारस्टोर में हमारे पास होगा

    constructor() {
    this.structures = [];

    this.bindListeners({
        componentStatusChanged: SidebarActions.COMPONENT_STATUS_CHANGED
    })
}

    componentStatusChanged(data) {
    this.waitFor(DetailsStore);

    _.findWhere(this.structures[0].elem, {title: 'Example'}).enabled = data.value;
}

अब यहाँ आप देख सकते हैं, कि यह DetailsStore की प्रतीक्षा करेगा। इसका क्या मतलब है? कम या ज्यादा इसका मतलब है कि इस विधि को खुद को अपडेट करने से पहले DetailsStoreto अपडेट का इंतजार करना होगा।

tl; डॉ। वन स्टोर एक स्टोर में विधियों पर सुन रहा है, और घटक कार्रवाई से एक ट्रिगर करेगा, जो अपने स्वयं के स्टोर को अपडेट करेगा।

मुझे उम्मीद है कि यह आपकी किसी तरह मदद कर सकता है।


0

यदि आप घटकों के बीच संवाद स्थापित करने के विकल्पों का पता लगाना चाहते हैं और यह महसूस करना चाहते हैं कि यह कठिन और कठिन हो रहा है, तो आप एक अच्छे डिजाइन पैटर्न को अपनाने पर विचार कर सकते हैं: फ्लक्स

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

कई फ्लक्स कार्यान्वयन, और फेसबुक के आधिकारिक कार्यान्वयन हैं उनमें से एक है। हालाँकि, इसे वह माना जाता है जिसमें अधिकांश बॉयलरप्लेट कोड होते हैं, लेकिन यह समझना आसान है क्योंकि अधिकांश चीजें स्पष्ट हैं।

अन्य विकल्प में से कुछ हैं घबराना fluxxor fluxible और redux


0

मैं एक बार जहां आप अभी था, एक शुरुआत के रूप में आप कभी-कभी इस पर प्रतिक्रिया करने के तरीके पर जगह से बाहर महसूस करते हैं। मैं उसी तरह से निपटने की कोशिश कर रहा हूं, जैसा मैं अभी सोचता हूं।

राज्य संचार के लिए आधारशिला हैं

आमतौर पर यह नीचे आता है कि जिस तरह से आप इस घटक को अपने मामले में तीन घटकों को इंगित करते हैं उस स्थिति में परिवर्तन करते हैं।

<List />: जो संभवतः एक फिल्टर के आधार पर वस्तुओं की एक सूची प्रदर्शित करेगा <Filters />: फ़िल्टर विकल्प जो आपके डेटा को बदल देगा। <TopBar />: विकल्पों की सूची।

इस सहभागिता के सभी को ऑर्केस्ट्रेट करने के लिए आपको एक उच्च घटक की आवश्यकता है, आइए इसे ऐप कहते हैं, जो इस एक घटक में से प्रत्येक के लिए क्रियाओं और डेटा को पारित करेगा ताकि उदाहरण के लिए ऐसा दिख सके

<div>
  <List items={this.state.filteredItems}/>
  <Filter filter={this.state.filter} setFilter={setFilter}/>
</div>

तो जब setFilterयह कहा जाता है तो यह फ़िल्टर किए गए को प्रभावित करेगा और दोनों घटक को फिर से प्रस्तुत करेगा ;; यदि यह पूरी तरह से स्पष्ट नहीं है, तो मैंने आपको चेकबॉक्स के साथ एक उदाहरण दिया है जिसे आप एकल फ़ाइल में देख सकते हैं:

import React, {Component} from 'react';
import {render} from 'react-dom';

const Person  = ({person, setForDelete}) => (
          <div>
            <input type="checkbox" name="person" checked={person.checked} onChange={setForDelete.bind(this, person)} />
            {person.name}
          </div>
);


class PeopleList extends Component {

  render() {

    return(
      <div>
       {this.props.people.map((person, i) => {
         return <Person key={i} person={person} setForDelete={this.props.setForDelete} />;
       })}
       <div onClick={this.props.deleteRecords}>Delete Selected Records</div>
     </div>
    );
  }

} // end class

class App extends React.Component {

  constructor(props) {
    super(props)
    this.state = {people:[{id:1, name:'Cesar', checked:false},{id:2, name:'Jose', checked:false},{id:3, name:'Marbel', checked:false}]}
  }

  deleteRecords() {
    const people = this.state.people.filter(p => !p.checked);

    this.setState({people});
 }

  setForDelete(person) {
    const checked = !person.checked;
    const people = this.state.people.map((p)=>{
      if(p.id === person.id)
        return {name:person.name, checked};
      return p;
    });

    this.setState({people});
  }

  render () {

    return <PeopleList people={this.state.people} deleteRecords={this.deleteRecords.bind(this)} setForDelete={this.setForDelete.bind(this)}/>;
  }
}

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

0

निम्नलिखित कोड मुझे दो भाई-बहनों के बीच संचार स्थापित करने में मदद करता है। सेटअप रेंडर () और कंपोनेंटडिमाउंट () कॉल के दौरान उनके पैरेंट में किया जाता है। यह https://reactjs.org/docs/refs-and-the-dom.html पर आधारित है । आशा है कि यह मदद करता है।

class App extends React.Component<IAppProps, IAppState> {
    private _navigationPanel: NavigationPanel;
    private _mapPanel: MapPanel;

    constructor() {
        super();
        this.state = {};
    }

    // `componentDidMount()` is called by ReactJS after `render()`
    componentDidMount() {
        // Pass _mapPanel to _navigationPanel
        // It will allow _navigationPanel to call _mapPanel directly
        this._navigationPanel.setMapPanel(this._mapPanel);
    }

    render() {
        return (
            <div id="appDiv" style={divStyle}>
                // `ref=` helps to get reference to a child during rendering
                <NavigationPanel ref={(child) => { this._navigationPanel = child; }} />
                <MapPanel ref={(child) => { this._mapPanel = child; }} />
            </div>
        );
    }
}

यह टाइपस्क्रिप्ट है, शायद आपके उत्तर में उल्लेख किया जाना चाहिए। हालांकि अच्छी अवधारणा।
19 को सेराओसे

0

विचित्र रूप से किसी का उल्लेख नहीं है mobx। विचार के समान है redux। यदि मेरे पास एक डेटा है जिसे कई घटकों को सब्सक्राइब किया गया है, तो मैं इस डेटा का उपयोग कई घटकों को चलाने के लिए कर सकता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.