সেটস্টেট কেন সিঙ্কের পরিবর্তে অ্যাসিঙ্ককে রিএ্যাকটিজ করে?


126

আমি সবেমাত্র পেয়েছি যে this.setState()কোনও উপাদানগুলির মধ্যে প্রতিক্রিয়া ফাংশনটি অ্যাসিনক্রোনাস হয় বা এটি যে ফাংশনটি ডাকা হয়েছিল তার সমাপ্তির পরে বলা হয়।

এখন আমি এই ব্লগটি সন্ধান করেছি এবং খুঁজে পেয়েছি ( সেটস্টেট () স্টেট মিউটেশন অপারেশন রিঅ্যাক্টজেএসে সিঙ্ক্রোনাস হতে পারে )

এখানে তিনি দেখতে setStateপেলেন যে কীভাবে রাষ্ট্রের পরিবর্তন সূচিত হয়েছিল তার উপর নির্ভর করে অ্যাসিঙ্ক (স্ট্যাক খালি থাকাকালীন ডাকা হয়) বা সিঙ্ক (যত তাড়াতাড়ি কল করা হয়) বলা হয়।

এখন এই দুটি জিনিস হজম করা শক্ত

  1. ব্লগে setStateফাংশনটিকে একটি ফাংশনের অভ্যন্তরে বলা হয় updateState, তবে যা updateStateফাংশনকে ট্রিগার করেছিল তা এমন একটি জিনিস নয় যা একটি কথিত ফাংশন সম্পর্কে জানতে পারে।
  2. setStateজেএস একক থ্রেডেড ভাষা হওয়ায় তারা কেন এ্যাসিঙ্ক তৈরি করবে এবং এই সেটস্টেটটি কোনও ওয়েবএপিআই বা সার্ভার কল নয় তাই কেবল জেএসের থ্রেডে করতে হবে। তারা কী এমনটি করছে যাতে পুনর্নবীকরণ সমস্ত ইভেন্ট শ্রোতা এবং স্টাফগুলি বন্ধ না করে বা অন্য কোনও ডিজাইনের সমস্যা রয়েছে।


1
আমি আজ প্রায় জলবায়ু একটি বিট বর্ণনা করতে সাহায্য করে একটি নিবন্ধ লিখেছিলেন setState: medium.com/@agm1984/...
agm1984

উত্তর:


155

রাষ্ট্রীয় মান আপডেট হওয়ার পরে আপনি কোনও ফাংশন কল করতে পারেন:

this.setState({foo: 'bar'}, () => { 
    // Do something here. 
});

এছাড়াও, আপনার যদি একবারে আপডেট করার মতো প্রচুর রাজ্য থাকে তবে সেগুলি সমস্তগুলির মধ্যে সমানতে গ্রুপ করুন setState:

পরিবর্তে:

this.setState({foo: "one"}, () => {
    this.setState({bar: "two"});
});

শুধু এটি করুন:

this.setState({
    foo: "one",
    bar: "two"
});

16
হ্যাঁ ঠিক আছে আমরা একটি কলব্যাক ফাংশন পেয়েছি আমরা ব্যবহার করতে পারি তবে ডটসের প্রশ্ন নয়।
অনুপ

12
আশা করি এটি অন্য কাউকে কীভাবে এই প্রশ্নটি দেখে হোঁচট খায় help
জোটিডি

2
ইয়া ডাট সহায়ক হতে পারে
অনুপ

97

1) setStateক্রিয়াগুলি অ্যাসিনক্রোনাস এবং পারফরম্যান্স লাভের জন্য প্রস্তুত। এর ডকুমেন্টেশনে এটি ব্যাখ্যা করা হয়েছে setState

সেটস্টেট () অবিলম্বে এই.স্টেটকে রূপান্তরিত করে না তবে একটি মুলতুবি থাকা অবস্থায় অবস্থিতি স্থানান্তর তৈরি করে। এই পদ্ধতিটি কল করার পরে এটি.স্টেট অ্যাক্সেস করা সম্ভাব্যভাবে বিদ্যমান মানটি ফিরিয়ে আনতে পারে। সেটস্টেটে কলগুলির সিঙ্ক্রোনাস অপারেশনের কোনও গ্যারান্টি নেই এবং কলগুলি পারফরম্যান্স লাভের জন্য ব্যাচ করা যেতে পারে।


2) জেএস একটি একক থ্রেডেড ভাষা এবং এটি setStateকোনও ওয়েবএপিআই বা সার্ভার কল নয় কেন তারা সেটস্টেট অ্যাসিঙ্ক তৈরি করবে ?

এটি কারণ setStateরাষ্ট্র পরিবর্তন করে এবং পুনঃস্থাপনের কারণ হয়। এটি একটি ব্যয়বহুল অপারেশন হতে পারে এবং এটিকে সিঙ্ক্রোনাস করা ব্রাউজারটিকে প্রতিক্রিয়াবিহীন ছেড়ে দিতে পারে।

সুতরাং সেটস্টেট কলগুলি অ্যাসিক্রোনাসের পাশাপাশি আরও ভাল ইউআই অভিজ্ঞতা এবং পারফরম্যান্সের জন্য ব্যাচড।


59
যদি আপনার কোনও সেটস্টেট কল করার পরে ইভেন্টগুলির ক্রম নিশ্চিত করতে হয় তবে আপনি কলব্যাক ফাংশনটি পাস করতে পারেন। this.setState({ something: true }, () => console.log(this.state))
ianks

1
ব্যাখ্যার জন্য আপনাকে ধন্যবাদ সাচিন। যাইহোক, আমার এখনও সন্দেহ আছে, ব্লগটি ব্যাখ্যা করার সাথে সাথে এটি কি সমকালীন হতে পারে?
অজয় গৌড়

2
প্রতিক্রিয়া মধ্যে অন্য নির্বোধ নকশা সিদ্ধান্ত। রাজ্যের আপডেটটিকে সংশ্লেষপূর্ণ এবং উপস্থাপনাটিকে অবিচ্ছিন্ন করুন। আপনি রেন্ডারিংগুলিতে ব্যাচ করতে পারেন, তবে আমি জাতি শর্তের সাথে ডিল না করে রাষ্ট্রীয় পরিবর্তনশীল হিসাবে আদিম কিছু সেট করতে সক্ষম হতে চাই।
ig-dev

ফুকনেশনকে অ্যাসিঙ্ক বা সিঙ্ক করতে কেন কোনও বিকল্প সেট করার অনুমতি দিচ্ছেন না? এটি একটি দরকারী বৈশিষ্ট্য হবে
র্যান্ডাল কোডিং

স্পষ্টতই, আমি প্রতিক্রিয়া দলে নেই তবে আমার মতে, স্টেট আপডেট অ্যাসিঙ্ক করা ব্রাউজারগুলি একক থ্রেডযুক্ত। সিঙ্ক ক্রিয়াকলাপগুলি ইউআইকে প্রতিক্রিয়াহীন করতে পারে এবং এটি ইউআইয়ের পক্ষে ভাল প্রার্থী নয়।
শচীন

16

আমি জানি এই প্রশ্নটি পুরানো, তবে এটি আমাকে সহ দীর্ঘদিন ধরে অনেক রিঅ্যাক্টজ ব্যবহারকারীদের জন্য প্রচুর বিভ্রান্তির সৃষ্টি করে চলেছে। সম্প্রতি ড্যান আব্রামভ (প্রতিক্রিয়াশীল দল থেকে) সবেমাত্র কেন setStateঅ্যাসিঙ্ক হয় সে সম্পর্কে একটি দুর্দান্ত ব্যাখ্যা লিখেছিলেন :

https://github.com/facebook/react/issues/11527#issuecomment-360199710

setStateঅ্যাসিক্রোনাস হতে বোঝানো হয়েছে, এবং ড্যান আব্রামভের লিঙ্কযুক্ত ব্যাখ্যায় এর কয়েকটি সত্যিকারের ভাল কারণ রয়েছে। এর অর্থ এই নয় যে এটি সর্বদা অ্যাসিনক্রোনাস থাকবে - এর মূল অর্থ হল যে আপনি কেবল এটি সিঙ্ক্রোনাস হওয়ার উপর নির্ভর করতে পারবেন না । বাস্তবে কখন আপডেট হওয়া উচিত এবং আপনার উপাদানটি পুনরায় রেন্ডার করা হবে তা ঠিক করার জন্য রিঅ্যাক্টজেএস দৃশ্যের অনেকগুলি ভেরিয়েবল বিবেচনায় নেয় you're এটি প্রদর্শনের একটি সাধারণ উদাহরণ হ'ল আপনি যদি কোনও ব্যবহারকারীর ক্রিয়া প্রতিক্রিয়া হিসাবে কল করেন তবে সম্ভবত তাড়াতাড়ি আপডেট করা হবে (যদিও, আবার আপনি এটির উপর নির্ভর করতে পারবেন না), ফলে ব্যবহারকারী কোনও বিলম্ব অনুভব করবেন না , কিন্তু যদি আপনি কলstate
setStatestatesetState এজ্যাক্স কল প্রতিক্রিয়া বা ব্যবহারকারীর দ্বারা চালিত না হওয়া অন্য কোনও ইভেন্টের প্রতিক্রিয়া হিসাবে, তারপরে রাষ্ট্রটি সামান্য বিলম্বের সাথে আপডেট হতে পারে, যেহেতু ব্যবহারকারী সত্যিই এই বিলম্ব অনুভব করবেন না, এবং অপেক্ষা করার দ্বারা এটি কার্যকারিতা উন্নত করবে একাধিক রাজ্যের আপডেটগুলি একসাথে ব্যাচ করুন এবং ডিওএমকে আরও কয়েকবার রেন্ডার করুন।


আপনি কোনও উত্তরদাতাকে সঠিক হিসাবে চিহ্নিত করেন নি। লোকেরা কীভাবে এটি ঘুরতে হবে তা পোস্ট করছে। জিজ্ঞাসা করা প্রশ্নের উত্তর নয়। এই নিবন্ধটি ভাল মনে হচ্ছে।
অনুপ

@ আনুপ উত্তরটি কেবল 'অ্যাসিঙ্ক' বা 'সিঙ্ক' এর চেয়ে কিছুটা জটিল। এটি সর্বদা 'async' হিসাবে বিবেচিত হওয়া উচিত তবে কিছু ক্ষেত্রে 'সিঙ্ক' কাজ করে। আমি আশা করি আপনার জন্য আমি কিছুটা আলোকপাত করেছি।
গিলিব

8

ভাল নিবন্ধটি এখানে https://github.com/vasanthk/react-bit/blob/master/patterns/27.passing-function-to-setState.md

// assuming this.state.count === 0
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
// this.state.count === 1, not 3

Solution
this.setState((prevState, props) => ({
  count: prevState.count + props.increment
}));

বা কলব্যাক পাস this.setState ({.....},callback)

https://medium.com/javascript-scene/setstate-gate-abc10a9b2d82 https://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b



1

কোনও উপাদানটিতে কাউন্টার বাড়ানোর কল্পনা করুন:

  class SomeComponent extends Component{

    state = {
      updatedByDiv: '',
      updatedByBtn: '',
      counter: 0
    }

    divCountHandler = () => {
      this.setState({
        updatedByDiv: 'Div',
        counter: this.state.counter + 1
      });
      console.log('divCountHandler executed');
    }

    btnCountHandler = () => {
      this.setState({
        updatedByBtn: 'Button',
        counter: this.state.counter + 1
      });
      console.log('btnCountHandler executed');
    }
    ...
    ...
    render(){
      return (
        ...
        // a parent div
        <div onClick={this.divCountHandler}>
          // a child button
          <button onClick={this.btnCountHandler}>Increment Count</button>
        </div>
        ...
      )
    }
  }

পিতামাতা এবং সন্তানের উভয় উপাদানগুলির সাথে একটি গণনা হ্যান্ডলার সংযুক্ত রয়েছে। এটি উদ্দেশ্যমূলকভাবে সম্পন্ন করা হয়েছে যাতে আমরা একই ক্লিক ইভেন্ট বুদবুদ প্রসঙ্গে দুটি বার সেটস্টেট () সম্পাদন করতে পারি তবে 2 টি ভিন্ন হ্যান্ডলারের মধ্যে থেকে।

যেমনটি আমরা কল্পনা করব, বোতামের একক ক্লিক ইভেন্টটি এখন উভয় হ্যান্ডলারগুলিকে ট্রিগার করবে যেহেতু বুদবুদ পর্যায়ের সময় ইভেন্টটি বুদবুদ থেকে লক্ষ্য থেকে বাহ্যতম ধারক পর্যন্ত যায়।

অতএব বিটিএনকাউন্টহ্যান্ডলার () প্রথমে মৃত্যুদন্ড কার্যকর করে, গণনাটি 1-তে বাড়িয়ে প্রত্যাশিত এবং ডিভোকাউন্টহ্যান্ডলার () মৃত্যুদন্ড কার্যকর করে, গণনাটি 2-তে বাড়িয়ে তুলবে বলে আশা করা হচ্ছে।

তবে প্রতিক্রিয়া বিকাশকারী সরঞ্জামগুলিতে পরিদর্শন করতে পারেন বলে গণনাটি কেবলমাত্র 1 এ বৃদ্ধি পেয়েছে।

এটি প্রমাণ করে যে প্রতিক্রিয়া জানায়

  • সমস্ত সেটস্টেট কলগুলি সারি করে

  • প্রসঙ্গে শেষ পদ্ধতিটি কার্যকর করার পরে এই কাতারে ফিরে আসে (এই ক্ষেত্রে ডিভাউন্টহ্যান্ডলার)

  • একযোগে একাধিক সেটস্টেট কলগুলির মধ্যে ঘটে যাওয়া সমস্ত অবজেক্ট মিউটেশনগুলি একই প্রসঙ্গে একত্রিত করে (একক ইভেন্ট পর্বের মধ্যে সমস্ত পদ্ধতি কল যেমন একই প্রসঙ্গে) একীভূত রূপান্তর সিনট্যাক্সে মার্জ হয়ে যায় (মার্জ করা অর্থপূর্ণ কারণ এটিই আমরা রাষ্ট্রের বৈশিষ্ট্যগুলি স্বাধীনভাবে আপডেট করতে পারি সেটস্টেটে () প্রথম স্থানে)

  • এবং একাধিক সেটস্টেট () কলগুলির কারণে এটি পুনরায় রেন্ডারিং রোধ করতে এটি একটি একক সেটস্টেট () এ পাস করে (এটি ব্যাচিংয়ের খুব আদিম বর্ণনা)।

প্রতিক্রিয়াশীল কোড দ্বারা চালিত প্রতিক্রিয়া:

this.setState({
  updatedByDiv: 'Div',
  updatedByBtn: 'Button',
  counter: this.state.counter + 1
})

এই আচরণটি থামাতে, সেটস্টেট পদ্ধতিতে যুক্তি হিসাবে বস্তুগুলি পাস করার পরিবর্তে কলব্যাকগুলি পাস করা হয়।

    divCountHandler = () => {
          this.setState((prevState, props) => {
            return {
              updatedByDiv: 'Div',
              counter: prevState.counter + 1
            };
          });
          console.log('divCountHandler executed');
        }

    btnCountHandler = () => {
          this.setState((prevState, props) => {
            return {
              updatedByBtn: 'Button',
              counter: prevState.counter + 1
            };
          });
      console.log('btnCountHandler executed');
    }

শেষ পদ্ধতিটি সম্পাদন শেষ করার পরে এবং সেটস্টেট সারিটি প্রক্রিয়া করার জন্য যখন প্রতিক্রিয়া দেখায়, কেবল পূর্ববর্তী উপাদান অবস্থায় প্রবাহিত প্রতিটি সেটস্টেটের সারি জন্য কলব্যাকটি কেবল কল করে।

এইভাবে প্রতিক্রিয়াটি নিশ্চিত করে যে সারিতে থাকা সর্বশেষ কলব্যাকটি তার পূর্ববর্তী সমস্ত অংশীদারদের হাত ধরে রেখেছে রাষ্ট্রটি আপডেট করতে পারে।


0

হ্যাঁ, সেটস্টেট () হ'ল অবিচ্ছিন্ন।

লিঙ্কটি থেকে: https://reactjs.org/docs/react-component.html#setstate

  • প্রতিক্রিয়া গ্যারান্টি দেয় না যে রাষ্ট্র পরিবর্তনগুলি সঙ্গে সঙ্গে প্রয়োগ করা হবে।
  • সেটস্টেট () সর্বদা অবিলম্বে উপাদানটি আপডেট করে না।
  • উপাদানটি আপডেট করার জন্য তাত্ক্ষণিক কমান্ডের চেয়ে সেটস্টেট () কে অনুরোধ হিসাবে ভাবেন।

কারণ তারা
লিঙ্কটি থেকে ভাবেন : https://github.com/facebook/react/issues/11527#issuecomment-360199710

... আমরা সম্মত হই যে সেটস্টেট () পুনরায় রেন্ডারিং সিঙ্ক্রোনালিভাবে অনেক ক্ষেত্রে অকার্যকর হবে

অসিনক্রোনাস সেটস্টেট () যাঁরা শুরু করেছিলেন এবং দুর্ভাগ্যবশত তারা অভিজ্ঞতা অর্জন করেছেন তাদের পক্ষে জীবনকে খুব কঠিন করে তোলে:
- অপ্রত্যাশিত রেন্ডারিং ইস্যু: বিলম্বিত রেন্ডারিং বা কোনও রেন্ডারিং (প্রোগ্রাম লজিকের উপর ভিত্তি করে)
- প্যারামিটারগুলি পাশ করা
অন্যান্য বিষয়গুলির মধ্যে একটি বড় বিষয়।

নীচে উদাহরণ সাহায্য করেছে:

// call doMyTask1 - here we set state
// then after state is updated...
//     call to doMyTask2 to proceed further in program

constructor(props) {
    // ..

    // This binding is necessary to make `this` work in the callback
    this.doMyTask1 = this.doMyTask1.bind(this);
    this.doMyTask2 = this.doMyTask2.bind(this);
}

function doMyTask1(myparam1) {
    // ..

    this.setState(
        {
            mystate1: 'myvalue1',
            mystate2: 'myvalue2'
            // ...
        },    
        () => {
            this.doMyTask2(myparam1); 
        }
    );
}

function doMyTask2(myparam2) {
    // ..
}

আশা করি এইটি কাজ করবে.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.