मैं हुक useState और useEffects का उपयोग करके प्रतिक्रिया पर 60 के दशक का समय बनाना चाहता हूं यही मैं कर रहा हूं

import '../assets/css/timer.css'
import { useState, useEffect } from 'react'

const Timer = () =>{

    const [ time, setTime ] = useState(0);

    useEffect(()=>{
        if(time!==60){
            setInterval(()=>{
                    setTime(prevTime => prevTime+1) ;
            }, 1000);
        }
        
    
    }, [])


    return(
        <>

            <div className="circular">
                <div className="inner"></div>
                <div className="outer"></div>
                <div className="numb">
                    {time}  // Place where i am displaying time
                </div>
                <div className="circle">
                    <div className="dot">
                    <span></span>
                    </div>
                    <div className="bar left">
                    <div className="progress"></div>
                    </div>
                    <div className="bar right">
                    <div className="progress"></div>
                    </div>
                </div>
            </div>
        </>
    )
}

export default Timer

टाइमर रुक नहीं रहा है। यह हमेशा के लिए जारी है। मैंने यह भी कोशिश की है

    useEffect(()=>{

        setInterval(()=>{
            if(time!==60)
                setTime(prevTime => prevTime+1) ;
        }, 1000);
    
    }, [])

क्या कुछ कृपया समझा सकते हैं कि चीजें कहां गलत हो रही हैं।

0
Ujjwal Chaudhary 7 जुलाई 2021, 21:20

3 जवाब

सबसे बढ़िया उत्तर

आप इसे अपने पहले प्रयास के साथ काम करने के करीब हैं, लेकिन कुछ समस्याएं हैं।

मुख्य समस्या यह है कि आप एक खाली निर्भरता सरणी पास करते हैं, जिसका अर्थ है कि यह केवल पहले रेंडर पर चलेगा और लगातार रेंडर पर अपडेट नहीं किया जाएगा। दूसरे, आप रिटर्न या 'क्लीन अप' प्रदान नहीं करते हैं जिसका अर्थ है कि अंतराल कभी भी साफ़ नहीं होता है।

  useEffect(() => {
    if (time < 60) {
      const timer = setInterval(() => {
        setTime(prevTime => prevTime + 1);
      }, 1000);

      return () => clearInterval(timer);
    }
  }, [time])

यहां हम निर्भरता सरणी में time पास करते हैं और सशर्त अंतराल सेट करते हैं यदि time आपके समाप्ति समय से कम है, आपके मामले में 60 लेकिन मैंने इसे 5 तक छोटा कर दिया है ताकि आप इसे रोक सकें। हम एक return कॉलबैक भी पास करते हैं जो प्रत्येक रेंडर चक्र के अंत में अंतराल को साफ़ कर देगा।

इस सेट अप के साथ हर बार सेटइंटरवल time स्थिति को अपडेट करता है, उपयोग प्रभाव पिछले रेंडर के अंत में अंतराल को साफ़ कर देगा, और फिर वर्तमान रेंडर में फिर से चलाएँ यदि समय सीमा से कम है तो अंतराल को फिर से सेट करें .

इस तरह से रिएक्ट रेंडर चक्र का उपयोग करने का लाभ, अंतराल कॉलबैक में अंतराल को साफ़ करने के बजाय, यह आपको अपने टाइमआउट का बारीक नियंत्रण देता है - जिससे आप आसानी से आगे की जाँच जोड़ सकते हैं या अन्य राज्य मूल्यों के आधार पर समय बढ़ा / छोटा कर सकते हैं .

const { useState, useEffect } = React;

const Timer = () => {
  const [time, setTime] = useState(0);

  useEffect(() => {
    if (time < 5) {
      const timer = setInterval(() => {
        setTime(prevTime => prevTime + 1);
      }, 1000);

      return () => clearInterval(timer);
    }
  }, [time])

  return (
    <div className="circular">
      <div className="numb">
        {time}
      </div>
    </div>
  )
}

ReactDOM.render(
  <Timer />,
  document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="root"></div>
0
pilchard 8 जुलाई 2021, 09:06

useEffect(..., []) केवल एक बार चलेगा, इसलिए इसके अंदर का time कभी भी अपडेट नहीं होगा। तो आपको setTime फ़ंक्शन के अंदर prevTime की जांच करने की आवश्यकता है, और उसके बाद ही वृद्धि करें यदि यह 60 नहीं है। यदि यह है, तो आपको अंतराल को साफ़ करना चाहिए, और फिर आपको चाहिए उपयोग प्रभाव की सफाई में अंतराल साफ़ करें:

useEffect(()=>{
    const i = setInterval(() => {
        setTime(prevTime => {
            if (prevTime !== 60) return prevTime+1;
            clearInterval(i);
            return prevTime;
        });
    }, 1000);
    return () => clearInterval(i);
}, [])
1
dave 7 जुलाई 2021, 18:26

आपको सेटटाइमआउट को अनमाउंट स्थिति में साफ़ करना होगा

कार्यात्मक घटक के लिए

useEffect(()=>{
  const i = setInterval(() => {
    setTime(prevTime => {
        if (prevTime !== 60) return prevTime+1;
        clearInterval(i);
        return prevTime;
    });
  }, 1000);
  return () => clearInterval(i);
}, [])

वर्ग घटक के लिए

componentWillUnmount() {
  this.clearInterval()
}
0
Jyotsna maurya 7 जुलाई 2021, 18:31