फिर से प्रस्तुत करने के लिए एक Redux जुड़ा घटक कैसे जानता है?


86

मैं शायद बहुत स्पष्ट रूप से कुछ याद कर रहा हूं और खुद को साफ करना चाहूंगा।

यहाँ मेरी समझ है।
एक भोली प्रतिक्रिया घटक में, हमारे पास statesऔर है props। संपूर्ण घटक stateको setStateपुन: प्रस्तुत करने के साथ अद्यतन करना । propsज्यादातर केवल पढ़े जाते हैं और उन्हें अपडेट करने से कोई मतलब नहीं है।

एक प्रतिक्रिया घटक में जो एक रेडक्स स्टोर की सदस्यता लेता है, जैसे कुछ के माध्यम से store.subscribe(render), यह स्पष्ट रूप से हर टाइम स्टोर के लिए फिर से रेंडर करता है।

प्रतिक्रिया-रिडक्स में एक सहायक होता है connect()जो राज्य के पेड़ के हिस्से को इंजेक्ट करता है (जो कि घटक के लिए रुचि रखता है) और घटक के रूप में एक्शन क्रिएटर्स props, आमतौर पर कुछ के माध्यम से

const TodoListComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

लेकिन इस समझ के साथ कि रिडक्स स्टेट ट्री चेंज (री-रेंडर) पर प्रतिक्रिया के लिए setStateआवश्यक है TodoListComponent, मुझे घटक फ़ाइल में कोई भी stateया setStateसंबंधित कोड नहीं मिल सकता है TodoList। यह कुछ इस तरह से पढ़ता है:

const TodoList = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

क्या कोई मुझे सही दिशा में इंगित कर सकता है कि मैं क्या याद कर रहा हूं?

पुनश्च मैं toux सूची उदाहरण का अनुसरण कर रहा हूं, जो रिडक्स पैकेज के साथ बंडल किया गया है

जवाबों:


109

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

डैन अब्रामोव ने connect( कनेक्ट.जेएस ) का एक बड़ा सरलीकृत संस्करण लिखा , जो मूल विचार को दिखाता है, हालांकि यह अनुकूलन कार्य में से कोई भी नहीं दिखाता है। मेरे पास Redux प्रदर्शन पर कई लेखों के लिंक हैं जो कुछ संबंधित विचारों पर चर्चा करते हैं।

अपडेट करें

रिएक्ट-रेडक्स v6.0.0 ने कुछ प्रमुख आंतरिक परिवर्तन किए कि कैसे जुड़े घटक स्टोर से अपना डेटा प्राप्त करते हैं।

उसी के हिस्से के रूप में, मैंने एक पोस्ट लिखी है जिसमें बताया गया है कि connectएपीआई और उसके इंटर्न कैसे काम करते हैं, और समय के साथ वे कैसे बदल गए हैं:

मुहावरेदार Redux: द हिस्ट्री एंड इंप्लीमेंटेशन ऑफ रिएक्ट-रेडक्स


धन्यवाद! क्या आप वही व्यक्ति हैं जिन्होंने दूसरे दिन @ HN - news.ycombinator.com/item?id=12307621 उपयोगी लिंक के साथ मेरी मदद की? आपसे मिलकर अच्छा लगा :)
जो लुईस

4
हाँ, मुझे लगता है कि :) मैं खर्च रास्ता बहुत अधिक समय ऑनलाइन Redux पर विचार विमर्श के लिए देख - रेडिट, HN, अतः, मध्यम, और विभिन्न अन्य स्थानों पर। मदद करने में खुशी! (इसके अलावा FYI करें, मैं डिस्क पर रिएक्टिफ़्लक्स चैट चैनलों की अत्यधिक अनुशंसा करता हूं। बहुत से लोग वहां बाहर घूम रहे हैं और सवालों के जवाब दे रहे हैं। मैं आमतौर पर ऑनलाइन यूएस ईएसटी का अनुभव करता हूं। आमंत्रण लिंक reactiflux.com पर है ।)
मार्करिक

यह मानते हुए सवाल का जवाब दिया, जवाब स्वीकार करने का मन? :)
मार्करैकन

क्या यह वस्तुओं की तुलना स्वयं या उन वस्तुओं के गुणों की तुलना पहले / बाद में करता है? यदि यह बाद की बात है, तो क्या यह केवल पहले स्तर की जांच करता है, क्या आप "उथले" से मतलब रखते हैं?
एंडी

हां, एक "उथले समानता की जांच" का अर्थ है प्रत्येक वस्तु के पहले स्तर के क्षेत्रों की तुलना करना prev.a === current.a && prev.b === current.b && .....:। यह मानता है कि किसी भी डेटा परिवर्तन के परिणामस्वरूप नए संदर्भ होंगे, जिसका अर्थ है कि प्रत्यक्ष म्यूटेशन के बजाय अपरिवर्तनीय डेटा अपडेट की आवश्यकता है।
मार्करसन

13

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


TLDR;

componentWillReceivePropsयह है कि कैसे stateनए के साथ समन्वयित रखा जा सकता है props

एज प्रकरण: एक बार stateअपडेट, तो अनुप्रयोग है फिर से प्रस्तुत करना!


यह पता चला है कि यदि आपका ऐप केवल stateअपने तत्वों को प्रदर्शित करने के लिए उपयोग propsकर रहा है state, तो अपडेट कर सकता है, लेकिन फिर से रेंडर नहीं करेगा।

मेरे पास stateऐसा था propsजो रिडक्स से प्राप्त पर निर्भर था store। मुझे जिस डेटा की आवश्यकता थी वह अभी तक स्टोर में नहीं था, इसलिए मैंने इसे प्राप्त किया componentDidMount, जैसा कि उचित है। मुझे प्रॉप्स वापस मिल गया, जब मेरे रेड्यूसर ने स्टोर को अपडेट किया, क्योंकि मेरा कंपोनेंट मैपस्टेटटाइपप्रॉप्स के माध्यम से जुड़ा हुआ है। लेकिन पेज प्रस्तुत नहीं किया, और राज्य अभी भी खाली तारों से भरा था।

इसका उदाहरण यह है कि किसी उपयोगकर्ता ने सहेजे गए url से "संपादन पोस्ट" पृष्ठ लोड किया है। आपके पास postIdurl से पहुंच है , लेकिन जानकारी storeअभी तक नहीं है, इसलिए आप इसे प्राप्त करते हैं। आपके पृष्ठ के आइटम नियंत्रित घटक हैं - इसलिए आपके द्वारा प्रदर्शित सभी डेटा अंदर हैं state

Redux का उपयोग करके, डेटा प्राप्त किया गया था, स्टोर अपडेट किया गया था, और घटक connectएड है, लेकिन ऐप परिवर्तनों को प्रतिबिंबित नहीं करता था। करीब से देखने पर propsप्राप्त हुए, लेकिन ऐप अपडेट नहीं हुआ। stateअद्यतन नहीं किया।

ठीक है, propsअद्यतन करेगा और प्रचार stateकरेगा , लेकिन नहीं होगा। आपको विशेष रूप stateसे अपडेट करने की आवश्यकता है ।

आप ऐसा नहीं कर सकते render(), और componentDidMountपहले ही समाप्त हो चुका है यह चक्र।

componentWillReceivePropsवह स्थान है जहाँ आप ऐसे stateगुणों को अद्यतन करते हैं जो परिवर्तित propमूल्य पर निर्भर करते हैं ।

उदाहरण उपयोग:

componentWillReceiveProps(nextProps){
  if (this.props.post.category !== nextProps.post.category){
    this.setState({
      title: nextProps.post.title,
      body: nextProps.post.body,
      category: nextProps.post.category,
    })
  }      
}

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

ReactJs घटक जीवनचक्र विधियाँ - एक गहरा गोता

componentWillReceivePropsवह जगह है जहां आप अपडेट के stateसाथ सिंक में रखने के लिए अपडेट करेंगे props

एक बार stateअपडेट करने के बाद फिर से रेंडर state करने पर निर्भर करता है !


3
से React 16.3बाद से, आप चाहिए का उपयोग getDerivedStateFromPropsकरने के बजाय componentWillReceiveProps। लेकिन वास्तव में, आपको वह सब भी नहीं करना चाहिए जैसा कि यहां
kyw

यह काम नहीं करता है, जब भी राज्य में बदलाव होता है तो कंपोनेंटलीरिविवप्रॉप्स इतने सारे मामले में काम करेंगे जब मैं यह काम नहीं करता हूं। विशेष रूप से, बहु स्तर नेस्ट या जटिल रंगमंच की सामग्री तो मैं एक आईडी और ट्रिगर इसके लिए करने के लिए अद्यतन स्थिति परिवर्तन और साथ असाइन घटक के लिए है नए डेटा फिर से प्रस्तुत करना
मई मौसम वीएन

0

यह उत्तर ब्रायन वॉन के लेख का एक सारांश है जिसका शीर्षक है कि आप शायद इसकी आवश्यकता न समझें राज्य (07 जून, 2018)।

प्रॉप्स से व्युत्पन्न राज्य अपने सभी रूपों में एक विरोधी पैटर्न है। जिसमें पुराने componentWillReceivePropsऔर नए का उपयोग करना शामिल है getDerivedStateFromProps

सहारा से राज्य प्राप्त करने के बजाय, निम्नलिखित समाधानों पर विचार करें।

दो सर्वोत्तम अभ्यास सिफारिशें

सिफारिश 1. पूरी तरह से नियंत्रित घटक
function EmailInput(props) {
  return <input onChange={props.onChange} value={props.email} />;
}
सिफारिश 2. एक कुंजी के साथ पूरी तरह से अनियंत्रित घटक
// parent class
class EmailInput extends Component {
  state = { email: this.props.defaultEmail };

  handleChange = event => {
    this.setState({ email: event.target.value });
  };

  render() {
    return <input onChange={this.handleChange} value={this.state.email} />;
  }
}

// child instance
<EmailInput
  defaultEmail={this.props.user.email}
  key={this.props.user.id}
/>

दो विकल्प यदि, किसी भी कारण से, सिफारिशें आपकी स्थिति के लिए काम नहीं करती हैं।

वैकल्पिक 1: एक आईडी प्रोप के साथ अनियंत्रित घटक रीसेट करें
class EmailInput extends Component {
  state = {
    email: this.props.defaultEmail,
    prevPropsUserID: this.props.userID
  };

  static getDerivedStateFromProps(props, state) {
    // Any time the current user changes,
    // Reset any parts of state that are tied to that user.
    // In this simple example, that's just the email.
    if (props.userID !== state.prevPropsUserID) {
      return {
        prevPropsUserID: props.userID,
        email: props.defaultEmail
      };
    }
    return null;
  }

  // ...
}
वैकल्पिक 2: एक आवृत्ति विधि के साथ अनियंत्रित घटक को रीसेट करें
class EmailInput extends Component {
  state = {
    email: this.props.defaultEmail
  };

  resetEmailForNewUser(newEmail) {
    this.setState({ email: newEmail });
  }

  // ...
}

-2

जैसा कि मुझे पता है कि केवल एक चीज redux करती है, स्टोर के राज्य बदलने पर घटक कॉल कर रहा है। यदि आप अपने घटक को उत्परिवर्तित स्थिति पर निर्भर थे और तब आपको अपने घटक को इसे अपडेट करने के लिए मजबूर करना चाहिए, ऐसा है

1-स्टोर स्टेट चेंज-2-कॉल (कंपोनेंटवैलिसेपप्रॉप्स () => {3-घटक स्टेट}}))

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