केवल एक बार रिएक्ट के उपयोग के साथ लोडिंग फ़ंक्शन को कैसे कॉल करें


205

UseEffect प्रतिक्रिया हुक हर बदलाव पर समारोह में पारित चलेंगे। वांछित गुणों में परिवर्तन होने पर ही इसे कॉल करने के लिए अनुकूलित किया जा सकता है।

क्या होगा यदि मैं एक आरंभीकरण फ़ंक्शन को कॉल करना चाहता हूं componentDidMountऔर परिवर्तनों पर इसे फिर से कॉल नहीं कर सकता हूं ? मान लें कि मैं एक इकाई लोड करना चाहता हूं, लेकिन लोडिंग फ़ंक्शन को घटक से किसी भी डेटा की आवश्यकता नहीं है। useEffectहुक का उपयोग करके हम इसे कैसे बना सकते हैं ?

class MyComponent extends React.PureComponent {
    componentDidMount() {
        loadDataOnlyOnce();
    }
    render() { ... }
}

हुक के साथ यह इस तरह दिख सकता है:

function MyComponent() {
    useEffect(() => {
        loadDataOnlyOnce(); // this will fire on every change :(
    }, [...???]);
    return (...);
}

जवाबों:


391

यदि आप केवल useEffectशुरुआती रेंडर के बाद दिए गए फ़ंक्शन को चलाना चाहते हैं , तो आप इसे दूसरे तर्क के रूप में एक खाली सरणी दे सकते हैं।

function MyComponent() {
  useEffect(() => {
    loadDataOnlyOnce();
  }, []);

  return <div> {/* ... */} </div>;
}

27
वैकल्पिक रूप से यदि आप डेटा प्राप्त करने के लिए उपयोग किए जाने वाले पैरा हैं (उदाहरण के लिए उपयोगकर्ता आईडी) तो आप उपयोगकर्ता आईडी को उस सरणी में पास कर सकते हैं और यदि यह घटक बदलता है तो डेटा को फिर से भर देगा। उपयोग के कई मामले उसी तरह काम करेंगे।
त्रिकोणीय

4
हाँ ... लंघन के बारे में और अधिक यहाँ प्रलेखित है: reactjs.org/docs/…
मेलुनेक

यह सबसे सरल उत्तर की तरह लगता है, लेकिन ESLint शिकायत करता है ... इस थ्रेड stackoverflow.com/a/56767883/1550587
साइमन हचिसन

बस निर्भरता सरणी में loadDataOnlyOnce पास करें। क्या वह काम करता है?
सितंबर

85

टी एल; डॉ

useEffect(yourCallback, []) - पहले रेंडर के बाद ही कॉलबैक ट्रिगर होगा।

विस्तृत विवरण

useEffectघटक के हर रेंडर के बाद डिफ़ॉल्ट रूप से चलता है (इस प्रकार एक प्रभाव पैदा होता है)।

जब useEffectआप अपने घटक में रखते हैं, तो आप एक प्रभाव के रूप में कॉलबैक को चलाना चाहते हैं। प्रतिक्रिया रेंडर करने के बाद और DOM अपडेट करने के बाद प्रभाव को चलाएगी।

यदि आप केवल कॉलबैक पास करते हैं - कॉलबैक प्रत्येक रेंडर के बाद चलेगा।

यदि दूसरा तर्क (सरणी) पास कर रहा है, तो रिएक्ट पहले रेंडर के बाद कॉलबैक चलाएगा और हर बार सरणी में मौजूद तत्वों में से एक को बदल दिया जाता है। उदाहरण के लिए, जब useEffect(() => console.log('hello'), [someVar, someOtherVar])- कॉलबैक पहले रेंडर के बाद चलेगा और किसी भी रेंडर के बाद someVarया उसमें से एक someOtherVarको बदल दिया जाएगा।

दूसरे तर्क को एक खाली सरणी पास करके, प्रतिक्रिया प्रत्येक सरणी को प्रस्तुत करने के बाद तुलना करेगी और देखेगी कि कुछ भी नहीं बदला गया है, इस प्रकार कॉलबैक को पहले रेंडर के बाद ही कॉल करना है।


68

का उपयोग करें हुक

घटक के आरोहण के बाद केवल एक बार फंक्शन चलाना एक ऐसा सामान्य पैटर्न है कि यह अपने आप में एक हुक को सही ठहराता है जो कार्यान्वयन विवरण को छुपाता है।

const useMountEffect = (fun) => useEffect(fun, [])

किसी भी कार्यात्मक घटक में इसका उपयोग करें।

function MyComponent() {
    useMountEffect(function) // function will run only once after it has mounted. 
    return <div>...</div>;
}

UseMountEffect हुक के बारे में

useEffectदूसरे एरे तर्क के साथ उपयोग करने पर, रिएक्ट बढ़ते (प्रारंभिक रेंडर) के बाद कॉलबैक चलाएगा और सरणी में मान बदल जाने के बाद। चूंकि हम एक खाली सरणी से गुजरते हैं, यह बढ़ते हुए ही चलेगा।


19
मैं आपके उत्तर को बहुत पसंद करता हूं, क्योंकि ESLint नियम "प्रतिक्रिया-हुक / थकाऊ-डिप्स" हमेशा खाली निर्भरता सूचियों पर विफल होगा। और उदाहरण के लिए प्रसिद्ध क्रिएट-रिएक्शन-ऐप टेम्पलेट उस नियम को लागू करेगा।
डायलाटन

1
पूरी तरह से @Dynalon से सहमत हैं। यह स्वीकृत समाधान होना चाहिए क्योंकि यह ESLint नियम में हस्तक्षेप नहीं करता है
मिकाडो 68

धन्यवाद @Dynalon और Mikado68 :-)। निर्णय ओपी का विशेषाधिकार है। मुझे आपकी टिप्पणियों के बारे में सूचित किया गया था, लेकिन ओपी नहीं था। आप सीधे सवाल पर टिप्पणी करके उसे सुझाव दे सकते हैं।
बेन कार्प

2
अब आप उपयोग कर सकते हैं useMountजब आपके प्रभाव फ़ंक्शन को प्रॉपर से कुछ की आवश्यकता होती है, लेकिन कभी भी फिर से चलाने की आवश्यकता नहीं होती है, भले ही लिंटर वार्न के बिना वह मूल्य बदल जाए: useEffect(()=>console.log(props.val),[])लापता निर्भरता चेतावनी useMount(()=>console.log(props.val))होगी, लेकिन चेतावनी का कारण नहीं होगा लेकिन "काम नहीं करता है"। मुझे यकीन नहीं है कि हालांकि समवर्ती मोड के साथ कोई समस्या होगी।
HMR

1
मुझे यह पसंद है :) पूर्व राज्य के रूप में एक ही कारण; ESLint नियम इस बारे में शिकायत नहीं करेगा, इसके अलावा इसका नाम एक खाली सरणी की तुलना में समझना आसान है
Frexuz

20

दूसरे तर्क के रूप में खाली सरणी पास करें useEffectडॉक्स को उद्धृत करते हुए यह प्रभावी रूप से रिएक्ट बताता है :

यह रिएक्ट बताता है कि आपका प्रभाव किसी भी मूल्य पर या प्रॉप्स पर निर्भर नहीं करता है, इसलिए इसे फिर से चलाने की आवश्यकता नहीं है।

यहाँ एक स्निपेट है जिसे आप यह दिखाने के लिए चला सकते हैं कि यह काम करता है:

function App() {
  const [user, setUser] = React.useState(null);

  React.useEffect(() => {
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        setUser(data.results[0]);
      });
  }, []); // Pass empty array to only run once on mount.
  
  return <div>
    {user ? user.name.first : 'Loading...'}
  </div>;
}

ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>


4

मैं एक mountफ़ंक्शन को परिभाषित करना पसंद करता हूं , यह उसी तरह से EsLint को चकमा देता useMountहै और मुझे यह अधिक आत्म-व्याख्यात्मक लगता है।

const mount = () => {
  console.log('mounted')
  // ...

  const unmount = () => {
    console.log('unmounted')
    // ...
  }
  return unmount
}
useEffect(mount, [])

-1

चाल यह है कि useEffect एक दूसरा पैरामीटर लेता है।

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

या, कुछ भी नहीं:

import React, { useEffect } from 'react';

function App() {
  useEffect(() => {

    // Run! Like go get some data from an API.

  }, []); //Empty array as second argument

  return (
    <div>
      {/* Do something with data. */}
    </div>
  );
}

यह सुनिश्चित करेगा कि उपयोग केवल एक बार ही चलता है।

डॉक्स से नोट करें:

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


3
यदि आपकी सीएसएस ट्रिक्स से शाब्दिक रूप से कॉपी / पेस्ट करना, तो आप कम से कम अपने स्रोत को क्रेडिट कर सकते हैं। css-tricks.com/run-useeffect-only-once
burtyish
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.