जीवन चक्र विधि getDerivedStateFromProps का उपयोग कैसे करें


142

ऐसा लग रहा है कि componentWillReceivePropsआने वाले रिलीज में पूरी तरह से एक नई जीवनचक्र पद्धति के पक्ष में होने जा रहा है getDerivedStateFromProps: स्थिर getDerivedStateFromProps ()

निरीक्षण करने पर, ऐसा लगता है कि अब आप के बीच एक प्रत्यक्ष तुलना करने में असमर्थ हैं this.propsऔर nextProps, जैसे आप में कर सकते हैं componentWillReceiveProps। क्या इसके आसपास कोई रास्ता है?

इसके अलावा, यह अब एक वस्तु देता है। क्या मैं यह मानने के लिए सही हूं कि वापसी मूल्य अनिवार्य रूप से है this.setState?

नीचे एक उदाहरण है जो मैंने ऑनलाइन पाया: प्रॉप्स / राज्य से प्राप्त राज्य

इससे पहले

class ExampleComponent extends React.Component {
  state = {
    derivedData: computeDerivedState(this.props)
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.someValue !== nextProps.someValue) {
      this.setState({
        derivedData: computeDerivedState(nextProps)
      });
    }
  }
}

उपरांत

class ExampleComponent extends React.Component {
  // Initialize state in constructor,
  // Or with a property initializer.
  state = {};

  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.someMirroredValue !== nextProps.someValue) {
      return {
        derivedData: computeDerivedState(nextProps),
        someMirroredValue: nextProps.someValue
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}

जवाबों:


96

इसे हटाने के बारे में componentWillReceiveProps: आपको इसके उपयोग को संभालने में सक्षम होना चाहिए getDerivedStateFromPropsऔर componentDidUpdate, उदाहरण के माइग्रेशन के लिए प्रतिक्रिया ब्लॉग पोस्ट देखें । और हाँ, वस्तु getDerivedStateFromPropsको उसी तरह राज्य में अद्यतन करके लौटा दिया गया है जिस तरह से पास की गई वस्तु है setState

यदि आपको वास्तव में किसी प्रॉप के पुराने मूल्य की आवश्यकता है, तो आप हमेशा अपने राज्य में इसे कुछ इस तरह से कैश कर सकते हैं:

state = {
  cachedSomeProp: null
  // ... rest of initial state
};

static getDerivedStateFromProps(nextProps, prevState) {
  // do things with nextProps.someProp and prevState.cachedSomeProp
  return {
    cachedSomeProp: nextProps.someProp,
    // ... other derived state properties
  };
}

कुछ भी जो राज्य को प्रभावित नहीं करता है componentDidUpdate, उसमें डाला जा सकता है , और यहां तक ​​कि getSnapshotBeforeUpdateबहुत ही निम्न-स्तरीय सामान के लिए भी है।

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


1
ऊ, मैंने सवाल गड़बड़ कर दिया। मेरा वास्तव में मतलब थाcomponentWillReceiveProps
एंड्रयू

2
मैंने अपने राज्य का उपयोग पिछले प्रॉप्स को रखने के लिए करने का सोचा था, लेकिन मैं वास्तव में इसे लागू करने के लिए अतिरिक्त कोड और तर्क से बचना चाहता था। मैं आपके द्वारा लाई गई कुछ अन्य चीजों को देख रहा हूँ। बहुत धन्यवाद!
एंड्रयू

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

2
@AxeEffect ऐसा इसलिए है क्योंकि यह getDerivedStateFromPropsवास्तव में कभी भी संस्मरण के लिए नहीं था । कृपया नीचे मेरा उत्तर देखें जहां मैंने इसके बजाय अनुशंसित दृष्टिकोण का वर्णन किया है
दान अब्रामोव

यह एक टाइपो है? क्या आपको याद आया ...? क्या हमें पूरे राज्य की वस्तु या केवल उस हिस्से को वापस करना चाहिए जिसकी हमें परवाह है।
theprogrammer

51

हम के रूप में प्रतिक्रिया ब्लॉग हाल ही में पर पोस्ट , अधिकांश मामलों में आप की जरूरत नहीं है getDerivedStateFromPropsसब पर

यदि आप कुछ व्युत्पन्न डेटा की गणना करना चाहते हैं, तो:

  1. अंदर ही करो render
  2. या, यदि यह फिर से गणना करना महंगा है, तो एक संस्मरण सहायक का उपयोग करें memoize-one

यहाँ "सरल" उदाहरण के बाद:

import memoize from "memoize-one";

class ExampleComponent extends React.Component {
  getDerivedData = memoize(computeDerivedState);

  render() {
    const derivedData = this.getDerivedData(this.props.someValue);
    // ...
  }
}

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


45
यह आवश्यक नहीं है, तो विशाल मामलों के बहुमत, तो मैं हैरान हूँ इस तरह के एक बुरी तरह से की जरूरत परिवर्तन किया गया है एक है कि काम कर परियोजनाओं के हजारों टूट जाएगा। लगता है कि रिएक्ट टीम इंजीनियरिंग से अधिक शुरू हुई।
Ska

39
ComponentsWillReceiveProps से getDerivedStateFromProps में बदलें। यह टूट नहीं रहा है बल्कि सभी मौजूदा कोड को रिफलेक्टर करने के लिए मजबूर कर रहा है, जो बहुत समय लेने वाला है। और बहुत कम लाभ के लिए लगता है क्योंकि आप कहते हैं कि आपको इसका उपयोग अधिकांश मामलों में नहीं करना चाहिए। किसी ऐसी चीज़ के लिए एपीआई बदलने की परेशानी से क्यों गुज़रना चाहिए जिसका इस्तेमाल पहले भी नहीं किया जाना चाहिए।
Ska

4
मुझे दान अब्रामोव की इस टिप्पणी का जवाब पसंद आएगा।
15

6
@DanAbramov यह परिवर्तन क्यों आया, इस पर कोई जवाब?
पेट्रोस काइराकौ

3
वास्तव में हमारी परियोजनाओं में यह बहुत उपयोग किया जाता है। जब नया डेटा नीचे आता है, तो स्क्रीन पर स्नैकबार जैसी चीजें दिखाने के लिए, 1 उदाहरण। componentWillReceivePropsसरल था और यह काम किया। इस स्थैतिक कचरे के लिए इसे क्यों हटाएं ...
ओलिवर डिक्सन

6

जैसा कि दान अब्रामोव ने बताया है

इसे रेंडर के अंदर ही करें

हम वास्तव में राज्य गणना के लिए किसी भी प्रकार के समीपवर्ती प्रॉप्स के लिए संस्मरण के साथ उस दृष्टिकोण का उपयोग करते हैं।

हमारा कोड इस तरह दिखता है

// ./decorators/memoized.js  
import memoizeOne from 'memoize-one';

export function memoized(target, key, descriptor) {
  descriptor.value = memoizeOne(descriptor.value);
  return descriptor;
}

// ./components/exampleComponent.js
import React from 'react';
import { memoized } from 'src/decorators';

class ExampleComponent extends React.Component {
  buildValuesFromProps() {
    const {
      watchedProp1,
      watchedProp2,
      watchedProp3,
      watchedProp4,
      watchedProp5,
    } = this.props
    return {
      value1: buildValue1(watchedProp1, watchedProp2),
      value2: buildValue2(watchedProp1, watchedProp3, watchedProp5),
      value3: buildValue3(watchedProp3, watchedProp4, watchedProp5),
    }
  }

  @memoized
  buildValue1(watchedProp1, watchedProp2) {
    return ...;
  }

  @memoized
  buildValue2(watchedProp1, watchedProp3, watchedProp5) {
    return ...;
  }

  @memoized
  buildValue3(watchedProp3, watchedProp4, watchedProp5) {
    return ...;
  }

  render() {
    const {
      value1,
      value2,
      value3
    } = this.buildValuesFromProps();

    return (
      <div>
        <Component1 value={value1}>
        <Component2 value={value2}>
        <Component3 value={value3}>
      </div>
    );
  }
}

इसके लाभ यह हैं कि आपको तुलनात्मक बॉयलरप्लेट के टन को अंदर करने की आवश्यकता नहीं है getDerivedStateFromPropsया componentWillReceivePropsआप एक निर्माणकर्ता के अंदर कॉपी-पेस्ट आरंभीकरण को छोड़ सकते हैं।

ध्यान दें:

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

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