प्रतिक्रिया हुक का उपयोग करें (केवल घटक के लिए सफाई )WillUnmount?


94

मुझे इस कोड के परिणाम के बारे में आसानी से बताएं।

const ForExample = () => {
    const [name, setName] = useState('');
    const [username, setUsername] = useState('');

    useEffect(() => {
        console.log('effect');
        console.log({
            name,
            username
        });

        return () => {
            console.log('cleaned up');
            console.log({
                name,
                username
            });
        };
    }, [username]);

    const handleName = e => {
        const { value } = e.target;

        setName(value);
    };

    const handleUsername = e => {
        const { value } = e.target;

        setUsername(value);
    };

    return (
        <div>
            <div>
                <input value={name} onChange={handleName} />
                <input value={username} onChange={handleUsername} />
            </div>
            <div>
                <div>
                    <span>{name}</span>
                </div>
                <div>
                    <span>{username}</span>
                </div>
            </div>
        </div>
    );
};

जब ForExample componentmounts, 'प्रभाव' लॉग इन किया जाएगा। यह से संबंधित है componentDidMount()

और जब भी मैं नाम इनपुट बदलता हूं, तो 'प्रभाव' और 'क्लीन अप' दोनों लॉग हो जाएंगे। इसके विपरीत, जब भी मैं [username]दूसरे पैरामीटर में जोड़ा जाता हूं, तब से कोई भी संदेश लॉग नहीं किया जाएगा useEffect()। यह से संबंधित हैcomponentDidUpdate()

अंत में, जब ForExample componentअनमाउंट, 'क्लीन अप' लॉग हो जाएगा। यह से संबंधित है componentWillUnmount()

हम सब जानते हैं कि।

जब भी घटक को फिर से प्रस्तुत किया जा रहा हो, तो 'साफ-सुथरा' किया जाता है।

मैं प्रवेश करने के लिए इस घटक केवल पल जब यह अनमाउंट है के लिए 'साफ' बनाना चाहते हैं, मैं सिर्फ का दूसरा पैरामीटर बदलना होगा useEffect()करने के लिए []

लेकिन अगर मैं बदल [username]जाता हूं [], तो नाम इनपुट ForExample componentके componentDidUpdate()लिए लागू नहीं होता है।

मैं क्या करना चाहता हूँ, घटक बनाने के componentDidUpdate()लिए केवल नाम इनपुट और दोनों के लिए समर्थन करता है componentWillUnmount()। (केवल घटक के अनमाउंट होने पर 'सफाई के लिए' लॉगिंग करें)


4
आपके 2 अलग-अलग प्रभाव हो सकते हैं। एक जिसे usernameदूसरे तर्क के रूप में इसके साथ एक सरणी दिया जाता है, और एक जिसे दूसरे तर्क के रूप में एक खाली सरणी दिया जाता है।
थोलले

@ टोलल क्या आपका मतलब है कि मुझे 2 अलग-अलग उपयोग करना है () तरीके?
कू

1
हाँ, इसके बारे में जाने का एक तरीका है।
थोलले

1
@ मुझे लगता है कि यह अंतिम उपयोग () विधि से आगे निकल जाएगा। मै कोशिश करुॅगा। धन्यवाद
कू

2
महान! आपका स्वागत है। यह इस बात पर निर्भर करता है कि सफाई क्या करनी चाहिए। 2 अलग-अलग प्रभाव एक बुरा समाधान नहीं है।
थोलले

जवाबों:


87

चूंकि सफाई पर निर्भर नहीं है username, आप सफाई को एक अलग तरह से रख सकते हैं useEffectजिसे दूसरे तर्क के रूप में एक खाली सरणी दी गई है।

उदाहरण

const { useState, useEffect } = React;

const ForExample = () => {
  const [name, setName] = useState("");
  const [username, setUsername] = useState("");

  useEffect(
    () => {
      console.log("effect");
    },
    [username]
  );

  useEffect(() => {
    return () => {
      console.log("cleaned up");
    };
  }, []);

  const handleName = e => {
    const { value } = e.target;

    setName(value);
  };

  const handleUsername = e => {
    const { value } = e.target;

    setUsername(value);
  };

  return (
    <div>
      <div>
        <input value={name} onChange={handleName} />
        <input value={username} onChange={handleUsername} />
      </div>
      <div>
        <div>
          <span>{name}</span>
        </div>
        <div>
          <span>{username}</span>
        </div>
      </div>
    </div>
  );
};

function App() {
  const [shouldRender, setShouldRender] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setShouldRender(false);
    }, 5000);
  }, []);

  return shouldRender ? <ForExample /> : null;
}

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

<div id="root"></div>


अच्छा और साफ उदाहरण। मैं हालांकि सोच रहा हूँ। क्या मैं परिवर्तित नेविगेशन पर किसी तरह उपयोग प्रभाव को ट्रिगर कर सकता हूं, या मुझे इसे घटक ट्री में ऊपर ले जाना होगा? क्योंकि जब आपके "क्लीयर अप" यूज़ को पेस्ट करते हैं तो मुझे यह ट्रिगर दिखाई नहीं दे रहा है।
फेबियन बोस्लर

121

आप एक से अधिक उपयोग कर सकते हैं उपयोग करें

उदाहरण के लिए अगर मेरा वैरिएबल data1 है तो मैं अपने कंपोनेंट में इस सब का उपयोग कर सकता हूं

useEffect( () => console.log("mount"), [] );
useEffect( () => console.log("will update data1"), [ data1 ] );
useEffect( () => console.log("will update any") );
useEffect( () => () => console.log("will update data1 or unmount"), [ data1 ] );
useEffect( () => () => console.log("unmount"), [] );

5
पहले और अंतिम उपयोगों के बीच अंतर क्या है, पहले का उपयोग करें या तो विलोमाउंट या डिमाउंट पर लागू किया जाएगा , अंतिम उपयोग के बाद खाली सरणी के साथ कॉल बैक फ़ंक्शन को वापस क्यों दिया गया था? क्या आप प्रत्येक उपयोग का विस्तृत वर्णन कर सकते हैं कि हम कब और कैसे उपयोग कर सकते हैं?
सिलुवरु किरन कुमार

4
कॉलबैक के @siluverukirankumar रिटर्न वैल्यू (फंक्शन) को नष्ट (अनमाउंट इवेंट) कहा जा रहा है। यही कारण है कि अंतिम उदाहरण एक एचओसी है, जो तुरंत कार्य करता है। दूसरा पैरामीटर वह है जहां रिएक्ट इस हुक को फिर से बदलने के लिए दिखेगा। जब यह एक खाली सरणी होती है तो यह सिर्फ एक बार चलती है।
जॉर्जियाई

3
धन्यवाद @Georgy को मिला यह अंतिम उपयोग है। वापसी स्पष्ट रूप से नहीं देखी गई कॉलबैक है
सिल्वेरु किरन कुमार

2
इसलिए, यदि आप एक उपयोग हुक बनाते हैं, और यह एक फ़ंक्शन देता है .. तो दिए गए फ़ंक्शन से पहले कोड एक घटक के रूप में चलता है ... और दिए गए फ़ंक्शन में कोड को घटकव्यूनेम के लिए कहा जाता है? यह थोड़ा भ्रमित करने वाला है, इसलिए यह सुनिश्चित करना कि मैं सही समझ रहा हूं। useEffect (() => {// माउंट पर चलने के लिए कोड ... वापसी () => {// कोड को चलाने के लिए}}) क्या यह सही है?
मैय्या

मेरा सुझाव है कि overreacted.io/a-complete-guide-to-useeffect को पढ़ने के जीवनकाल में हुक के बारे में सोचना वास्तव में इतना मीठा नहीं है
मोटो

2
function LegoComponent() {

  const [lego, setLegos] = React.useState([])

  React.useEffect(() => {
    let isSubscribed = true
    fetchLegos().then( legos=> {
      if (isSubscribed) {
        setLegos(legos)
      }
    })
    return () => isSubscribed = false
  }, []);

  return (
    <ul>
    {legos.map(lego=> <li>{lego}</li>)}
    </ul>
  )
}

उपरोक्त कोड में, fetchLegos फ़ंक्शन एक वादा लौटाता है। हम उपयोग के दायरे में एक सशर्त होने के वादे को "रद्द" कर सकते हैं, ऐप को घटक के अनमाउंट होने के बाद राज्य की स्थापना से रोक सकता है।

चेतावनी: अनमाउंट किए गए घटक पर प्रतिक्रिया स्थिति अद्यतन नहीं कर सकता। यह एक नो-ऑप है, लेकिन यह आपके एप्लिकेशन में मेमोरी लीक होने का संकेत देता है। उपयोग करने के लिए, क्लीनअप फ़ंक्शन में सभी सदस्यताएँ और अतुल्यकालिक कार्यों को रद्द करें।


1

बहुत से जटिल कार्यों और विधियों को बनाने के बजाय, मैं एक इवेंट श्रोता बनाता हूं और मैन्युअल रूप से इसे करने की चिंता किए बिना स्वचालित रूप से मेरे लिए माउंट और अनमाउंट किया है। यहाँ एक उदाहरण है।

//componentDidMount
useEffect( () => {

    window.addEventListener("load",  pageLoad);

    //component will unmount
    return () => {
       
        window.removeEventListener("load", pageLoad);
    }

 });

अब जब यह भाग पूरा हो गया है तो मैं इस तरह पेजलोड फ़ंक्शन से बस कुछ भी चला सकता हूं।

const pageLoad = () =>{
console.log(I was mounted and unmounted automatically :D)}

0

useEffect अपने दायरे में अलग-थलग है और तदनुसार प्रदान किया जाता है। Https://reactjs.org/docs/hooks-custom.html से छवि

यहां छवि विवरण दर्ज करें


किसी समाधान का लिंक स्वागत योग्य है, लेकिन कृपया सुनिश्चित करें कि आपका उत्तर इसके बिना उपयोगी है: लिंक के चारों ओर संदर्भ जोड़ें ताकि आपके साथी उपयोगकर्ताओं को यह पता चले कि यह क्या है और यह क्यों है, तो पृष्ठ के सबसे प्रासंगिक हिस्से को उद्धृत करें ' मामले में लक्ष्य पृष्ठ अनुपलब्ध होने पर पुनः लिंक करना। उत्तर जो किसी लिंक से थोड़ा अधिक हैं, उन्हें हटाया जा सकता है
Богдан Опир
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.