প্রতিক্রিয়া কি রাষ্ট্রের আপডেটের জন্য অর্ডার রাখে?


139

আমি জানি যে প্রতিক্রিয়া পারফরম্যান্স অপ্টিমাইজেশনের জন্য অ্যাসিক্রোনারস এবং ব্যাচে স্টেট আপডেটগুলি সম্পাদন করতে পারে। সুতরাং আপনি কখনই রাষ্ট্রকে ডাকার পরে আপডেট হওয়ার বিষয়ে বিশ্বাস করতে পারবেন না setState। তবে আপনি কি একই পরিস্থিতিতে রাজ্যটিকে আপডেট করারsetState জন্য প্রতিক্রিয়াটিকে বিশ্বাস করতে পারেন, যেমনটি বলা হয়

  1. একই উপাদান?
  2. বিভিন্ন উপাদান?

নিম্নলিখিত উদাহরণগুলির বোতামটি ক্লিক করে বিবেচনা করুন:

১. এমন কি কখনও সম্ভাবনা আছে যে কটি মিথ্যা এবং খ সত্য :

class Container extends React.Component {
  constructor(props) {
    super(props);
    this.state = { a: false, b: false };
  }

  render() {
    return <Button onClick={this.handleClick}/>
  }

  handleClick = () => {
    this.setState({ a: true });
    this.setState({ b: true });
  }
}

২. এমন কি কখনও সম্ভাবনা আছে যে কটি মিথ্যা এবং খ সত্য :

class SuperContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { a: false };
  }

  render() {
    return <Container setParentState={this.setState.bind(this)}/>
  }
}

class Container extends React.Component {
  constructor(props) {
    super(props);
    this.state = { b: false };
  }

  render() {
    return <Button onClick={this.handleClick}/>
  }

  handleClick = () => {
    this.props.setParentState({ a: true });
    this.setState({ b: true });
  }
}

মনে রাখবেন যে এটি আমার ব্যবহারের ক্ষেত্রে চরম সরলীকরণ। আমি বুঝতে পারি যে আমি এটি আলাদাভাবে করতে পারি, উদাহরণস্বরূপ, উদাহরণস্বরূপ 1 হিসাবে একই সাথে উভয় রাষ্ট্রের প্যারামগুলি আপডেট করা, পাশাপাশি উদাহরণস্বরূপ প্রথম স্টেট আপডেটের কলব্যাকের মধ্যে দ্বিতীয় রাষ্ট্রের আপডেট সম্পাদন করা 2. তবে, এটি আমার প্রশ্ন নয়, এবং আমি কেবলমাত্র সেখানেই যদি আগ্রহী a

ডকুমেন্টেশন দ্বারা ব্যাক আপ করা যে কোনও উত্তর প্রশংসিত হয়।


1
: এই দেখুন stackoverflow.com/a/36087156/3776299
helb

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

উদাহরণস্বরূপ এটি গ্রহণ করুন: github.com/facebook/react/issues/11793 , আমি বিশ্বাস করি যে ইস্যুতে আলোচিত বিষয়গুলি অনেক বিকাশকারীদের পক্ষে সহায়ক হবে তবে সেই জিনিসটি সরকারী ডক্সে নেই , কারণ এফবি লোকেরা এটিকে উন্নত বলে মনে করে। একই জিনিস সম্ভবত অন্যান্য জিনিস সম্পর্কে। আমি মনে করব, 'রাজ্য ব্যবস্থাপনায় গভীরতার সাথে প্রতিক্রিয়া' বা 'রাজ্য পরিচালনার ক্ষতিগুলি' জাতীয় শিরোনামের একটি অফিসিয়াল নিবন্ধটি আপনার প্রশ্নের মতো রাজ্য ব্যবস্থাপনার সমস্ত কোণার অন্বেষণ করা খারাপ হবে না। হতে পারে আমরা এফবি বিকাশকারীদের এই জাতীয় স্টাফ দিয়ে ডকুমেন্টেশন বাড়ানোর জন্য চাপ দিতে পারি :)
জিয়েরগিম

আমার প্রশ্নের মাঝারিটিতে একটি দুর্দান্ত নিবন্ধটির লিঙ্ক Th এটি 95% রাষ্ট্রীয় ব্যবহারের ক্ষেত্রে আবশ্যক। :)
মিশাল 14

2
@ মিচাল কিন্তু সেই নিবন্ধটি এখনও এই প্রশ্নের উত্তর দেয় না আইএমএইচও
জর্জিিম

উত্তর:


335

আমি প্রতিক্রিয়া কাজ।

TLDR:

তবে আপনি কি সেটাকে স্টেট আপডেট করার অনুরোধে একই স্থানে রাষ্ট্র আপডেট করার জন্য প্রতিক্রিয়াটিকে বিশ্বাস করতে পারেন

  • একই উপাদান?

হ্যাঁ.

  • বিভিন্ন উপাদান?

হ্যাঁ.

অর্ডার আপডেটের সবসময় বিবেচনা করা হয়। আপনি তাদের মধ্যে "মধ্যবর্তী" অবস্থা দেখেন কিনা বা আপনি কোনও ব্যাচে রয়েছেন কিনা তার উপর নির্ভর করে।

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

ভবিষ্যতের সংস্করণগুলিতে (সম্ভবত 17 এবং তার পরে প্রতিক্রিয়া করুন), প্রতিক্রিয়াটি ডিফল্ট অনুসারে সমস্ত আপডেটগুলি ব্যাচ করে দেবে যাতে আপনার এটি সম্পর্কে চিন্তা করতে হবে না। সর্বদা হিসাবে, আমরা প্রতিক্রিয়া ব্লগ এবং রিলিজ নোটগুলিতে এ সম্পর্কে যে কোনও পরিবর্তন ঘোষণা করব ।


এটি বোঝার মূল বিষয়টিsetState() হ'ল আপনি কোনও প্রতিক্রিয়া ইভেন্ট হ্যান্ডলারের অভ্যন্তরে কয়টি উপাদানই কল করুন না কেন , ইভেন্টের শেষে তারা কেবলমাত্র একক পুনরায় রেন্ডার তৈরি করবে । বৃহত অ্যাপ্লিকেশনগুলিতে ভাল পারফরম্যান্সের জন্য এটি গুরুত্বপূর্ণ কারণ যদি ক্লিক ইভেন্ট হ্যান্ডল করার সময় Childএবং যদি Parentপ্রতিটি কল হয় setState(), আপনি Childদুবার পুনরায় রেন্ডার করতে চান না ।

আপনার উভয় উদাহরণে, setState()কলগুলি একটি প্রতিক্রিয়া ইভেন্ট হ্যান্ডলারের ভিতরে ঘটে। অতএব এগুলি ইভেন্টের শেষে সর্বদা একসাথে ফেলা হয় (এবং আপনি মধ্যবর্তী অবস্থা দেখতে পাবেন না)।

আপডেট সবসময় জিওপার্ডিতে অর্ডার তারা ঘটতে মধ্যে মিশে গিয়ে তৈরি । সুতরাং যদি প্রথম আপডেট হয় {a: 10}, দ্বিতীয়টি হয় {b: 20}এবং তৃতীয়টি হয় {a: 30}, রেন্ডার রাষ্ট্র হবে {a: 30, b: 20}। একই রাজ্যের কীতে সাম্প্রতিক আপডেট (যেমন aআমার উদাহরণের মতো) সর্বদা "জয়"।

this.stateবস্তু আপডেট করা হয় যখন আমরা ব্যাচ শেষে UI 'তে পুনরায় রেন্ডার। সুতরাং আপনার যদি আগের অবস্থার উপর ভিত্তি করে রাষ্ট্র আপডেট করার প্রয়োজন হয় (যেমন একটি কাউন্টার বাড়ানো), আপনার setState(fn)পড়া সংক্রান্ত পরিবর্তে আপনাকে কার্যক্ষম সংস্করণ ব্যবহার করা উচিত যা আপনাকে পূর্ববর্তী অবস্থা দেয় this.state। যদি আপনি এটির জন্য যুক্তি সম্পর্কে আগ্রহী হন তবে আমি এটিকে এই মন্তব্যে গভীরভাবে ব্যাখ্যা করেছি ।


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

যাইহোক, প্রতিক্রিয়া ১ earlier এবং পূর্ববর্তী সংস্করণ উভয়ই, ইভেন্ট ইভেন্ট হ্যান্ডলারের বাইরে ডিফল্টরূপে কোনও ব্যাচিং নেই । সুতরাং আপনার উদাহরণে যদি আমাদের পরিবর্তে AJAX প্রতিক্রিয়া হ্যান্ডলার handleClickথাকে setState()তবে প্রত্যেকটি এটি হওয়ার সাথে সাথেই প্রক্রিয়াজাত করা হবে। এই ক্ষেত্রে, হ্যাঁ, আপনি হবে কোন মধ্যবর্তী রাষ্ট্র দেখুন:

promise.then(() => {
  // We're not in an event handler, so these are flushed separately.
  this.setState({a: true}); // Re-renders with {a: true, b: false }
  this.setState({b: true}); // Re-renders with {a: true, b: true }
  this.props.setParentState(); // Re-renders the parent
});

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

promise.then(() => {
  // Forces batching
  ReactDOM.unstable_batchedUpdates(() => {
    this.setState({a: true}); // Doesn't re-render yet
    this.setState({b: true}); // Doesn't re-render yet
    this.props.setParentState(); // Doesn't re-render yet
  });
  // When we exit unstable_batchedUpdates, re-renders once
});

অভ্যন্তরীণ প্রতিক্রিয়া ইভেন্ট হ্যান্ডলারগুলি সমস্তই মোড়ানো হচ্ছে unstable_batchedUpdatesযার কারণে তারা ডিফল্টরূপে ব্যাচ করা হচ্ছে। নোট করুন যে একটি আপডেট unstable_batchedUpdatesদুটি বার মোড়ানোর কোনও প্রভাব নেই। আপডেটগুলি ফ্লাশ করা হয় যখন আমরা বাইরেরতম unstable_batchedUpdatesকলটি থেকে প্রস্থান করি ।

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


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


1
"সর্বদা অর্ডারটি সঠিকভাবে পেতে" এর একটি উপায় হ'ল একটি অস্থায়ী বস্তু তৈরি করা, বিভিন্ন মান নির্ধারণ (উদাহরণস্বরূপ obj.a = true; obj.b = true) এবং তারপরে শেষে ঠিক করুন this.setState(obj)। আপনি যদি কোনও ইভেন্ট হ্যান্ডলারের ভিতরে থাকেন তবে তা নির্বিশেষে এটি নিরাপদ। আপনি যদি ইভেন্ট হ্যান্ডলারের বাইরে প্রায়শই নিজেকে রাষ্ট্র নির্ধারণের ভুল করতে দেখেন তবে একটি ঝরঝরে কৌশল হতে পারে।
ক্রিস

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

1
এবং উপায় দ্বারা এর অর্থ হল যে আমরা এই স্টেট থেকে মোটেও পড়া উচিত নয়; কিছু state.X পড়ার একমাত্র যুক্তিযুক্ত উপায় হ'ল এটির যুক্তি থেকে এটি আপডেটের ফাংশনে পড়া। এবং, স্টেটে লেখাটিও অনিরাপদ। তাহলে কেন এখনই এই স্টেটে অ্যাক্সেসের অনুমতি দেওয়া হচ্ছে? এগুলি সম্ভবত একক প্রশ্ন করা উচিত তবে বেশিরভাগ ক্ষেত্রে আমি ব্যাখ্যাটি সঠিকভাবে পেয়েছি কিনা তা বোঝার চেষ্টা করছি।
মাকসিম গুমেরভ

10
এই উত্তরটি reactjs.org ডকুমেন্টেশনে যুক্ত করা উচিত
দ্বীন জন

2
componentDidUpdateপ্রতিক্রিয়া 16 হিসাবে যদি "প্রতিক্রিয়া ইভেন্ট হ্যান্ডলার" অন্তর্ভুক্ত এবং অন্যান্য জীবনচক্র কলব্যাকগুলি অন্তর্ভুক্ত থাকে তবে আপনি কি এই পোস্টে স্পষ্ট করে বলতে পারেন ? আগাম ধন্যবাদ!
ইভান

6

এটি আসলে বেশ আকর্ষণীয় প্রশ্ন তবে উত্তরটি খুব জটিল হওয়া উচিত নয়। মাধ্যমের এই দুর্দান্ত নিবন্ধটির একটি উত্তর রয়েছে।

1) আপনি যদি এটি করেন

this.setState({ a: true });
this.setState({ b: true });

আমি মনে করি না যে ব্যাচিংয়ের কারণে aএমন পরিস্থিতি হবে যেখানে থাকবে trueএবং bথাকবে ।false

তবে, যদি bনির্ভর করেa তবে সেখানে এমন পরিস্থিতি থাকতে পারে যেখানে আপনি প্রত্যাশিত রাজ্যটি পাবেন না।

// assuming this.state = { value: 0 };
this.setState({ value: this.state.value + 1});
this.setState({ value: this.state.value + 1});
this.setState({ value: this.state.value + 1});

উপরের সমস্ত কলগুলি প্রক্রিয়া করার পরে this.state.valueআপনার প্রত্যাশার মতো 1 টি নয়, 3 হবে।

এটি নিবন্ধে উল্লেখ করা হয়েছে: setState accepts a function as its parameter

// assuming this.state = { value: 0 };
this.setState((state) => ({ value: state.value + 1}));
this.setState((state) => ({ value: state.value + 1}));
this.setState((state) => ({ value: state.value + 1}));

এটা আমাদের দেবে this.state.value === 3


this.state.valueইভেন্ট হ্যান্ডলারগুলিতে (যেখানে setStateব্যাচ করা হয়) এবং এজেএক্স কলব্যাকস (যেখানে ব্যাচ করা setStateহয় না ) উভয়ই আপডেট হলে What ইভেন্ট হ্যান্ডলারগুলিতে আমি updater functionসর্বদা নিশ্চিত হয়ে থাকি যে ফাংশন দ্বারা সরবরাহিত বর্তমানে আপডেট হওয়া রাষ্ট্রটি ব্যবহার করে আমি রাষ্ট্রের আপডেট করব be setStateআমি জানি না যে এটি এ্যাচএক্স কলব্যাকের কোডের অভ্যন্তরে একটি আপডেটেটর ফাংশনটি ব্যবহার করা উচিত, যদিও আমি জানি যে এটি ব্যাচড নয়? আপনি কি setStateকোনও অ্যাজেএক্স কলব্যাকের মধ্যে আপডেটেটর ফাংশনটি ব্যবহার না করে বা ব্যবহার না করে দয়া করে পরিষ্কার করতে পারেন ? ধন্যবাদ!
টোনিক্স

@ মিচল, হাই মিশাল কেবলমাত্র প্রশ্ন জিজ্ঞাসা করতে চেয়েছিল, এটা কি সত্য যে আমাদের যদি এই সেট.সেট ({মান: 0}) থাকে; this.setState ({মান: this.state.value + 1}); প্রথম সেটস্টেট উপেক্ষা করা হবে এবং কেবল দ্বিতীয় সেটস্টেট কার্যকর করা হবে?
ডিকেনস

@ ডিকেনস আমি বিশ্বাস করি উভয়কেই setStateমৃত্যুদন্ড কার্যকর করা হবে তবে শেষটি জিতবে।
মিশাল

3

একই চক্র চলাকালীন একাধিক কল একসাথে ব্যাচ করা যেতে পারে। উদাহরণস্বরূপ, যদি আপনি একই চক্রে একবারে একাধিক আইটেম পরিমাণ বাড়ানোর চেষ্টা করেন, তবে এর সমতুল্য হবে:

Object.assign(
  previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)

https://reactjs.org/docs/react-component.html


3

যেমন ডক হিসাবে

সেটস্টেট () উপাদান উপাদানটিতে পরিবর্তনকে চিহ্নিত করে এবং প্রতিক্রিয়া জানায় যে এই উপাদানটি এবং তার শিশুদের আপডেট হওয়া রাষ্ট্রের সাথে পুনরায় রেন্ডার করা দরকার। ইভেন্ট হ্যান্ডলার এবং সার্ভারের প্রতিক্রিয়ার প্রতিক্রিয়া হিসাবে আপনি ব্যবহারকারী ইন্টারফেস আপডেট করতে এটি প্রাথমিক পদ্ধতি।

এটি সারিবদ্ধভাবে পরিবর্তনের প্রাকফর্ম করবে ( ফিফো : ফার্স্ট ইন ফার্স্ট আউট) প্রথম কলটি প্রথম সংশোধন করবে


হাই আলী, কেবল নিছক প্রশ্ন জিজ্ঞাসা করতে চেয়েছি, এটা কি সত্য যে আমাদের যদি এই সেট সেট ({মান: 0}) থাকে; this.setState ({মান: this.state.value + 1}); প্রথম সেটস্টেট উপেক্ষা করা হবে এবং কেবল দ্বিতীয় সেটস্টেট কার্যকর করা হবে?
ডিকেন্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.