প্রতি সেকেন্ডে উপাদানগুলির প্রতিক্রিয়া আপডেট করুন


114

আমি প্রতিক্রিয়া নিয়ে ঘুরে বেড়াচ্ছি এবং নিম্নলিখিত সময় উপাদানটি কেবল Date.now()পর্দায় রেন্ডার করে:

import React, { Component } from 'react';

class TimeComponent extends Component {
  constructor(props){
    super(props);
    this.state = { time: Date.now() };
  }
  render(){
    return(
      <div> { this.state.time } </div>
    );
  }
  componentDidMount() {
    console.log("TimeComponent Mounted...")
  }
}

export default TimeComponent;

প্রতিক্রিয়া দৃষ্টিকোণ থেকে সময়টি পুনরায় আঁকতে প্রতি সেকেন্ডে আপডেট করার এই উপাদানটি পাওয়ার সর্বোত্তম উপায় কী হবে?

উত্তর:


152

setIntervalপরিবর্তনটি ট্রিগার করতে আপনাকে ব্যবহার করতে হবে, তবে উপাদানটি ত্রুটিগুলি ছেড়ে যাওয়া এবং মেমরি ফাঁস রোধ করতে যখন আনমেন্ট করে তখন আপনাকে টাইমারটি সাফ করতে হবে:

componentDidMount() {
  this.interval = setInterval(() => this.setState({ time: Date.now() }), 1000);
}
componentWillUnmount() {
  clearInterval(this.interval);
}

2
আপনি যদি এমন একটি লাইব্রেরি চান যা এই ধরণের জিনিসকে আবদ্ধ করে রাখে, আমি তৈরি করেছিreact-interval-rerender
অ্যান্ডি

আমি আমার নির্ধারকটিতে আমার সেটআইন্টারভাল পদ্ধতিটি যুক্ত করেছি এবং এটি আরও ভাল কাজ করেছে।
akteifan

89

নিম্নলিখিত কোডটি React.js ওয়েবসাইট থেকে পরিবর্তিত উদাহরণ।

আসল কোডটি এখানে পাওয়া যায়: https://reactjs.org/#a-simple-comp घटक

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      seconds: parseInt(props.startTimeInSeconds, 10) || 0
    };
  }

  tick() {
    this.setState(state => ({
      seconds: state.seconds + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  formatTime(secs) {
    let hours   = Math.floor(secs / 3600);
    let minutes = Math.floor(secs / 60) % 60;
    let seconds = secs % 60;
    return [hours, minutes, seconds]
        .map(v => ('' + v).padStart(2, '0'))
        .filter((v,i) => v !== '00' || i > 0)
        .join(':');
  }

  render() {
    return (
      <div>
        Timer: {this.formatTime(this.state.seconds)}
      </div>
    );
  }
}

ReactDOM.render(
  <Timer startTimeInSeconds="300" />,
  document.getElementById('timer-example')
);

1
আমি কোনও কারণে এই পন্থাটি ব্যবহার করার সময় this.updater.enqueueSetState কোনও ফাংশন ত্রুটি নয় get setInterval কলব্যাক সঠিকভাবে এই উপাদান আবদ্ধ।
টাকরা

16
আমার মতো updater
মূর্খদের

3
ES6 এর সাথে আমার this.interval = setInterval (this.tick.bind (এটি), 1000) এর মতো একটি লাইন পরিবর্তন করতে হবে;
কপিল

আপনি কি ইউআরএলটির লিঙ্কটি উল্লেখ করতে পারেন? ধন্যবাদ ~
ফ্রেডারজ

আমি আরও দৃust়তার জন্য একটি ফর্ম্যাটিং পদ্ধতি এবং একটি "কনস্ট্রাক্টর" সম্পত্তি যুক্ত করেছি।
মিঃ পলিহর্ল

15

@ ওয়াইস্কি পরামর্শ দিয়েছেন:

setIntervalপরিবর্তনটি ট্রিগার করতে আপনাকে ব্যবহার করতে হবে, তবে উপাদানটি ত্রুটিগুলি ছেড়ে যাওয়া এবং মেমরি ফাঁস রোধ করতে যখন আনমেন্ট করে তখন আপনাকে টাইমারটি সাফ করতে হবে:

আপনি যদি হুক ব্যবহার করে একই জিনিসটি করতে চান:

const [time, setTime] = useState(Date.now());

useEffect(() => {
  const interval = setInterval(() => setTime(Date.now()), 1000);
  return () => {
    clearInterval(interval);
  };
}, []);

মন্তব্য সম্পর্কে:

আপনার ভিতরে কিছু পাস করার দরকার নেই []। আপনি যদি timeবন্ধনীগুলিতে পাস করেন তবে এর অর্থ প্রতিবার timeপরিবর্তনের মানটি প্রভাব চালানো , অর্থাত্‍ এটি setIntervalপ্রতিবারই নতুন timeপরিবর্তনের আহ্বান জানায় , পরিবর্তিত হয়, যা আমরা সন্ধান করছি না। setIntervalউপাদানটি মাউন্ট হয়ে যাওয়ার পরে আমরা কেবল একবারই আবেদন করতে চাই এবং তারপরে প্রতি 1000 সেকেন্ডে setIntervalকল করি setTime(Date.now())। অবশেষে, আমরা clearIntervalউপাদানটি আনমাউন্ট করা হলে অনুরোধ করব।

মনে রাখবেন যে timeপ্রতিবার timeপরিবর্তনের মান আপনি কীভাবে ব্যবহার করেছেন তার উপর ভিত্তি করে উপাদানটি আপডেট হয়ে যায় । যে নির্বাণ সঙ্গে কিছুই করার আছে time[]এর useEffect


1
[]দ্বিতীয় আর্গুমেন্ট হিসাবে আপনি একটি খালি অ্যারে ( ) কেন পাস করেছেন useEffect?
মেকোর মেলিরে

প্রতিক্রিয়া প্রভাব হুক উপর ডকুমেন্টেশন আমাদের বলে: "আপনি কি একটি প্রভাব চালান এবং শুধুমাত্র একবার এটা পরিষ্কার আপ (মাউন্ট এবং আনমাউন্ট দিকে) জন্য, আপনাকে একটি খালি অ্যারে ([]) একটি দ্বিতীয় আর্গুমেন্ট হিসাবে পাস করতে পারেন চান।" তবে ওপি চায় প্রতি প্রভাবটি প্রতি সেকেন্ডে চালিত হয়, অর্থাত্ পুনরায় ক্র্যাকিং, অর্থাৎ একবারে নয়।
মেকোর মেলিরে

পার্থক্যটি আমি লক্ষ্য করেছি আপনি যদি অ্যারেতে [সময়] পাস করেন তবে এটি প্রতিটি বিরতিতে উপাদানটি তৈরি এবং ধ্বংস করবে। আপনি যদি খালি অ্যারে পাস করেন [], এটি উপাদানটি সতেজ রাখে এবং পৃষ্ঠাটি ছাড়লে কেবল আনমাউন্ট করবে। তবে, উভয় ক্ষেত্রেই, এটির কাজটি পেতে, এটিকে আসলে রেন্ডার করার জন্য আমাকে কী = {সময়} বা কী = {তারিখ.নো () add যুক্ত করতে হয়েছিল।
তিবু

8

উপাদানটির componentDidMountজীবনচক্র পদ্ধতিতে, আপনি কোনও ফাংশন কল করার জন্য একটি বিরতি সেট করতে পারেন যা রাষ্ট্র আপডেট করে।

 componentDidMount() {
      setInterval(() => this.setState({ time: Date.now()}), 1000)
 }

4
সঠিক, তবে উপরের উত্তরের মতামত অনুসারে, মেমরি ফাঁস এড়াতে সময় সাফ করার জন্য মনে রাখবেন: घटकউইলউনমান্ট () {ClearInterval (this.interval); }
আলেকজান্ডার ফালক

3
class ShowDateTime extends React.Component {
   constructor() {
      super();
      this.state = {
        curTime : null
      }
    }
    componentDidMount() {
      setInterval( () => {
        this.setState({
          curTime : new Date().toLocaleString()
        })
      },1000)
    }
   render() {
        return(
          <div>
            <h2>{this.state.curTime}</h2>
          </div>
        );
      }
    }

0

সুতরাং আপনি সঠিক পথে ছিল। আপনার অভ্যন্তরে componentDidMount()আপনি setInterval()পরিবর্তনটি ট্রিগার করতে প্রয়োগের মাধ্যমে কাজটি শেষ করতে পারতেন তবে মনে রাখবেন যে কোনও উপাদান রাষ্ট্র আপডেট করার উপায়টি রয়েছে setState(), তাই আপনার অভ্যন্তরে componentDidMount()আপনি এটি করতে পারতেন:

componentDidMount() {
  setInterval(() => {
   this.setState({time: Date.now()})    
  }, 1000)
}

এছাড়াও, আপনি উপরের প্রস্তাবিত বাস্তবায়নটি Date.now()দিয়ে আপনি কোনটি কাজ করেন তা ব্যবহার করুন componentDidMount()তবে আপনি একটি নষ্ট সংখ্যা আপডেট করার একটি দীর্ঘ সেট পাবেন যা মানব পাঠযোগ্য নয়, তবে প্রযুক্তিগতভাবে এটি জানুয়ারি 1, 1970 থেকে প্রতি সেকেন্ডে মিলিসেকেন্ডে আপডেট করার সময়, তবে আমরা আমরা মনুষ্যগণ কীভাবে সময় পড়ি তা এই সময়কে পঠনযোগ্য করে তুলতে চাই, সুতরাং শিখতে এবং বাস্তবায়নের পাশাপাশি আপনি শিখতে setIntervalচান new Date()এবং toLocaleTimeString()এবং আপনি এটিকে এভাবে প্রয়োগ করবেন:

class TimeComponent extends Component {
  state = { time: new Date().toLocaleTimeString() };
}

componentDidMount() {
  setInterval(() => {
   this.setState({ time: new Date().toLocaleTimeString() })    
  }, 1000)
}

লক্ষ্য করুন আমি constructor()ফাংশনটিও সরিয়ে নিয়েছি , আপনার প্রয়োজনীয় প্রয়োজন হবে না, আমার রিফ্যাক্টরটি constructor()ফাংশনটির সাথে সাইটের সূচনা করার জন্য 100% সমতুল্য ।


0

প্রতিক্রিয়া ভি 16-তে পরিবর্তনের কারণে যেখানে উপাদানবিলিসিপপ্রসেস () অবমূল্যায়ন করা হয়েছে, এটি সেই পদ্ধতি যা আমি কোনও উপাদান আপডেট করার জন্য ব্যবহার করি। লক্ষ্য করুন যে নীচের উদাহরণটি টাইপস্ক্রিপ্টে রয়েছে এবং প্রপস আপডেট হওয়ার সাথে সাথে প্রারম্ভিক আপডেট এবং আপডেট হওয়া রাষ্ট্র পেতে স্ট্যাটিক গেটডেরিভ স্টেটফ্রোমপ্রস পদ্ধতি ব্যবহার করে।

    class SomeClass extends React.Component<Props, State> {
  static getDerivedStateFromProps(nextProps: Readonly<Props>): Partial<State> | null {
    return {
      time: nextProps.time
    };
  }

  timerInterval: any;

  componentDidMount() {
    this.timerInterval = setInterval(this.tick.bind(this), 1000);
  }

  tick() {
    this.setState({ time: this.props.time });
  }

  componentWillUnmount() {
    clearInterval(this.timerInterval);
  }

  render() {
    return <div>{this.state.time}</div>;
  }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.