আপনি সেটস্টেট কল না করে কোনও প্রতিক্রিয়া উপাদানকে পুনরায় রেন্ডার করতে বাধ্য করতে পারেন?


689

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

শীর্ষ স্তরের React.renderসাহায্যে এটি সম্ভব হয়েছে, তবে কোনও উপাদানগুলির মধ্যে এটি কাজ করে না (যা renderপদ্ধতিটি কেবল কোনও বস্তু ফেরায় বলে কিছুটা বোঝায় )।

এখানে একটি কোড উদাহরণ:

export default class MyComponent extends React.Component {

  handleButtonClick() {
    this.render();
  }

  render() {
    return (
      <div>
        {Math.random()}
        <button onClick={this.handleButtonClick.bind(this)}>
          Click me
        </button>
      </div>
    )
  }
}

অভ্যন্তরীণভাবে বোতামটি ক্লিক করা কল করে this.render(), তবে এটিই আসলে রেন্ডারিংয়ের কারণ হয় না (আপনি এটি কার্যকরভাবে দেখতে পারেন কারণ তৈরি করা পাঠ্যটি {Math.random()}পরিবর্তন হয় না)। তবে, আমি যদি কেবল this.setState()পরিবর্তে কল করি তবে this.render()এটি ঠিক আছে works

তাই আমি অনুমান আমার প্রশ্ন হলো, কি করতে প্রতিক্রিয়া উপাদান প্রয়োজন rerender করার জন্য রাষ্ট্র আছে? রাষ্ট্র পরিবর্তন না করে উপাদানটিকে চাহিদার আপডেট করতে বাধ্য করার কোনও উপায় আছে কি?


7
গৃহীত উত্তর বলছেন this.forceUpdate()অধিকার সমাধান যেহেতু সব উত্তর এবং বেশ কিছু মন্তব্য বাকি ব্যবহার বিরুদ্ধে forceUpdate()। তাহলে কি এই কথাটি বলা ঠিক হবে যে এখনও প্রশ্নের সঠিক সমাধান / উত্তর পাওয়া যায়নি?
আদি

6
ব্যতীত উত্তর আমার প্রশ্নের উত্তর দেয়। এটি হ'ল প্রযুক্তিগতভাবে আমি উত্তরটি খুঁজছিলাম এবং আমি এখনও সঠিক উত্তরটি মনে করি। অন্যান্য উত্তরগুলি আমি মনে করি ঠিক একই বিষয়ে সচেতন হতে লোকেদের জন্য ভাল পরিপূরক তথ্য।
ফিলিপ ওয়ালটন

মজার আকর্ষণীয় বিষয় হ'ল আপনি কোনও সরল বস্তুর সূচনা করার চেয়ে অন্য কোনও পর্যায়ে রাষ্ট্রীয় প্রয়োজন নেই, তারপরে এই.সেটস্টেট ({}) কে কেবল নতুন রেন্ডারকে ট্রিগার করে। প্রতিক্রিয়া দুর্দান্ত তবে মাঝে মাঝে অদ্ভুত। অতএব অতিরিক্ত নদীর গভীরতানির্ণয় ছাড়াই কোনও পরিবর্তন ট্রিগার করতে বা উপাদান উপাদান হিসাবে ডেটা নিয়ে উদ্বেগের সময় আপনি সরাসরি স্টোরগুলির ডেটা লুপ করতে পারেন।
জেসন সেব্রিং

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

উত্তর:


765

আপনার উপাদানগুলিতে, আপনি this.forceUpdate()কোনও পুনরায় সরবরাহকারীকে জোর করার জন্য কল করতে পারেন ।

ডকুমেন্টেশন: https://facebook.github.io/react/docs/comp घटक- api.html


169
আর একটি উপায় হ'ল this.setState (this.state);
কর

25
ফোর্সপেট ব্যবহার করা নিরুৎসাহিত করা হয়েছে, দয়া করে শেষ উত্তরটি দেখুন।
ভারান্দ পেজেস্কিয়ান

42
যদিও this.forceUpdate()প্রশ্নকারীদের সমস্যার খুব ভাল সমাধান নয় তবে এটি শিরোনামে উত্থিত প্রশ্নের সঠিক উত্তর। যদিও এটি সাধারণত এড়ানো উচিত, এমন পরিস্থিতিতে রয়েছে যখন ফোর্সআপ্টেট একটি ভাল সমাধান।
আর্নেহুগো 19

8
@kar প্রকৃতপক্ষে, shouldComponentUpdate()আপনার সমাধানটি নিষ্ক্রিয় করার জন্য অতিরিক্ত যুক্তি প্রয়োগ করা যেতে পারে ।
কিওয়ার্টি

4
সর্বাধিক কল স্ট্যাকের আকার অতিক্রম করেছে
24:36

327

forceUpdateএড়ানো উচিত কারণ এটি প্রতিক্রিয়াশীল মানসিকতা থেকে বিচ্যুত হয়। প্রতিক্রিয়া দস্তাবেজগুলি কখন forceUpdateব্যবহৃত হতে পারে তার একটি উদাহরণ তুলে ধরে :

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

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

সাধারণত আপনার ফোর্স আপডেট () এর সমস্ত ব্যবহার এড়াতে চেষ্টা করা উচিত এবং কেবল এটির থেকে পড়া উচিত এটি আপনার উপাদানটিকে "খাঁটি" এবং আপনার প্রয়োগকে আরও সহজ এবং আরও দক্ষ করে তোলে। forceUpdate ()

আপনি যে রেন্ডারটি পুনরায় রেন্ডার করতে চান সেটির কীটি পরিবর্তন করা কার্যকর হবে। রাষ্ট্রের মাধ্যমে আপনার উপাদানটিতে কী প্রপ সেট করুন এবং তারপরে আপনি যখন নতুন কী রাখতে সেট স্টেটটি আপডেট করতে চান।

<Element key={this.state.key} /> 

তারপরে একটি পরিবর্তন ঘটে এবং আপনি কীটি পুনরায় সেট করেন

this.setState({ key: Math.random() });

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

যদিও ওপি-র প্রশ্নের সঠিক উত্তর হ'ল forceUpdate()আমি এই সমাধানটি বিভিন্ন পরিস্থিতিতে সহায়ক বলে খুঁজে পেয়েছি। আমি মনে রাখতে চাই যে আপনি যদি নিজেকে ব্যবহার করে দেখেনforceUpdate দেখতে পান কোডটি পর্যালোচনা করতে এবং কাজ করার অন্য কোনও উপায় আছে কিনা তা দেখতে চাইতে পারেন।

নোট 1-9-2019:

উপরের (কীটি পরিবর্তন করা) উপাদানটিকে পুরোপুরি প্রতিস্থাপন করবে। পরিবর্তনগুলি ঘটানোর জন্য আপনি কীটি আপডেট করে নিজেকে আবিষ্কার করে দেখলে আপনার কোডটিতে অন্য কোনও সমস্যা থাকতে পারে। Math.random()কী ব্যবহার করে প্রতিটি রেন্ডার দিয়ে উপাদানটি পুনরায় তৈরি করবে। প্রতিক্রিয়া হিসাবে জিনিসগুলি পুনরায় রেন্ডার করার সর্বোত্তম উপায় নির্ধারণ করতে কীটি ব্যবহার করা হয় বলে এটিকে কী আপডেট করার পরামর্শ দেব না।


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

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

80
এটি হ্যাক এবং অপব্যবহার key। প্রথমত, এটির উদ্দেশ্যটি অস্পষ্ট। আপনি কেন keyএইভাবে ব্যবহার করছেন তা বুঝতে আপনার কোডের একজন পাঠককে কঠোর পরিশ্রম করতে হবে । দ্বিতীয়ত, এটি আর বিশুদ্ধ নয় forceUpdate। "খাঁটি" প্রতিক্রিয়াটির অর্থ হ'ল আপনার উপাদানটির ভিজ্যুয়াল উপস্থাপনা তার রাজ্যের উপর 100% নির্ভরশীল, তাই আপনি যদি কোনও রাজ্য পরিবর্তন করেন তবে তা আপডেট হয়। তবে, আপনার কাছে কিছু গভীরভাবে নেস্টেড অবজেক্ট রয়েছে ( forceUpdateদস্তাবেজগুলি এটি ব্যবহারের কারণ হিসাবে উদ্ধৃত করে) তবে ব্যবহারটি তা forceUpdateপরিষ্কার করে দেয়। তৃতীয়টি, Math.random()... এলোমেলো। তাত্ত্বিকভাবে, এটি একই র্যান্ডম সংখ্যা উত্পন্ন করতে পারে।
atomkirk

8
@xtraSimplicity আমি সম্মত হতে পারি না যে এটি জিনিসগুলির প্রতিক্রিয়া পদ্ধতির সাথে সম্মতি দেয়। forceUpdateএটি করার প্রতিক্রিয়া উপায়।
রব গ্রান্ট

3
@ রবার্ট গ্রান্ট, ফিরে তাকাতে, আমি সম্মত। যুক্ত জটিলতা সত্যই এটি মূল্যবান নয়।
এক্সট্রাস্পিলিটি

80

প্রকৃতপক্ষে, forceUpdate()একমাত্র সঠিক সমাধান যা অতিরিক্ত যুক্তি প্রয়োগ করা হয় বা যখন এটি সহজভাবে ফিরে আসে তখন পুনরায় রেন্ডার করতেsetState() পারে নাshouldComponentUpdate()false

forceUpdate ()

কলিং এড়িয়ে যাওয়া, উপাদানটিতে কল করার forceUpdate()কারণ হবে । আরও অনেক কিছু ...render()shouldComponentUpdate()

setState ()

setState()শর্তসাপেক্ষে রেন্ডারিং লজিকটি প্রয়োগ না করা হলে সর্বদা একটি রি-রেন্ডারকে ট্রিগার করবে shouldComponentUpdate()আরও অনেক কিছু ...


forceUpdate() আপনার উপাদানগুলির মধ্যে থেকে কল করা যেতে পারে this.forceUpdate()


হুকস: আমি কীভাবে উপাদানগুলিকে প্রতিক্রিয়াতে হুকের সাথে পুনরায় রেন্ডার করতে বাধ্য করতে পারি?


বিটিডাব্লু: আপনি কি রাষ্ট্র পরিবর্তন করছেন বা আপনার নেস্টেড সম্পত্তিগুলি প্রচার করে না?


1
একটি আকর্ষণীয় বিষয় লক্ষণীয় হ'ল সেট স্টেটের বাইরের স্টেট অ্যাসিমেন্টগুলি যেমন এই.স্টেট.ফু = 'বার' রেন্ডার
লাইফসাইकल

4
@ lfender6445 কনস্ট্রাক্টরের this.stateবাইরের সাথে সরাসরি রাষ্ট্র নির্ধারণ করাতেও একটি ত্রুটি ছুঁড়ে ফেলা উচিত। 2016 সালে এটি করা যায়নি; তবে, আমি এখন নিশ্চিত এটি নিশ্চিত।
টাইলার

আমি সরাসরি রাষ্ট্রের কার্যভারের সাথে কাজ করার জন্য কিছু লিঙ্ক যুক্ত করেছি।
কিওয়ার্টি

36

আমি এড়িয়ে forceUpdateনিম্নলিখিতগুলি করে

ভুল উপায় : কী হিসাবে সূচকটি ব্যবহার করবেন না

this.state.rows.map((item, index) =>
   <MyComponent cell={item} key={index} />
)

সঠিক উপায় : ডেটা আইডি কী হিসাবে ব্যবহার করুন এটি কিছু গাইড ইত্যাদি হতে পারে

this.state.rows.map((item) =>
   <MyComponent item={item} key={item.id} />
)

সুতরাং এই জাতীয় কোড উন্নতি করে আপনার উপাদানটি অনন্য হবে এবং প্রাকৃতিকভাবে রেন্ডার হবে


this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
তাল

আমাকে সঠিক দিকের দিকে ঠেলে দেওয়ার জন্য আপনাকে অনেক ধন্যবাদ। কী হিসাবে সূচক ব্যবহার করা আমার সমস্যা ছিল।
রোইএক্স

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

34

আপনি যখন যোগাযোগের জন্য দুটি প্রতিক্রিয়া উপাদান চান, যা কোনও সম্পর্কের (পিতা-মাতা-সন্তানের) দ্বারা আবদ্ধ হয় না, তখন এটি ফ্লাক্স ব্যবহার করার পরামর্শ দেওয়া হয় বা অনুরূপ আর্কিটেকচার ।

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

সাধারণত আপনার ব্যবহার এড়াতে চেষ্টা করা উচিত forceUpdate()। ডকুমেন্টেশন থেকে:

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


2
কোন উপাদান রাষ্ট্রের স্মৃতি অবস্থা কী? যদি আমার একটি পৃষ্ঠায় পাঁচটি উপাদান থাকে এবং সেগুলি একটি একক দোকানে শোনা যায়, তবে আমার কাছে মেমরিতে পাঁচবার ডেটা আছে বা সেগুলি উল্লেখ রয়েছে? এবং এই সমস্ত শ্রোতা কি দ্রুত যুক্ত হয় না? আপনার টার্গেটে কেবল ডেটা দেওয়ার চেয়ে কেন "ট্রিকল ডাউন" করা ভাল?
এজেফারকাস

5
প্রকৃতপক্ষে প্রস্তাবনাগুলি হ'ল স্টোরের ডেটা উপাদান উপাদানগুলিতে প্রেরণ করা এবং কেবল স্ক্রোলের অবস্থা এবং অন্যান্য ছোট ছোট UI- নির্দিষ্ট জিনিসের জন্য উপাদান উপাদানটি ব্যবহার করা। আপনি যদি রিডেক্স ব্যবহার করেন (আমি এটি প্রস্তাব দিই), আপনি সরবরাহ করা ম্যাপিং ফাংশনের ভিত্তিতে যখনই প্রয়োজন হয় আপনি সংযোগ ফাংশনটি react-reduxস্বয়ংক্রিয়ভাবে স্টোরের স্টেটের স্টেটের স্টোর ম্যাপ করতে পারেন component
স্টিজন ডি উইট

1
@ এজেফারকাস রাজ্যটিকে কোনও স্টোরের ডেটাতে বরাদ্দ করা হবে যা যাইহোক এটির জন্য কেবলমাত্র পয়েন্টার তাই আপনি ক্লোনিং না করলে স্মৃতি কোনও সমস্যা নয়।
জেসন সেব্রিং

4
"ফোর্সআপডেট () সর্বদা এড়ানো উচিত" ভুল। ডকুমেন্টেশনটি স্পষ্টভাবে বলেছে: "সাধারণত আপনার বলপূর্বক () ব্যবহারের সমস্ত ব্যবহার এড়াতে চেষ্টা করা উচিত"। এর বৈধ ব্যবহারের কেস রয়েছেforceUpdate
এজেপি

2
@ এজেপি আপনি একেবারেই ঠিক বলেছেন, এটি ব্যক্তিগত পক্ষপাতিত্ব কথা ছিল :) আমি উত্তরটি সম্পাদনা করেছি।
gcedo

18

হুক ব্যবহার করুন বা এইচওসি আপনার বাছাই করুন

ব্যবহার আঙ্গুলসমূহ বা পরিকল্পিত (উচ্চতর ক্রম উপাদান) প্যাটার্ন , আপনি স্বয়ংক্রিয় আপডেটগুলো যখন আপনার দোকানে পরিবর্তন থাকতে পারে। এটি একটি কাঠামো ছাড়াই খুব হালকা ওজনের পদ্ধতির।

useStore হুক্স দোকান আপডেট হ্যান্ডেল করতে উপায়

interface ISimpleStore {
  on: (ev: string, fn: () => void) => void;
  off: (ev: string, fn: () => void) => void;
}

export default function useStore<T extends ISimpleStore>(store: T) {
  const [storeState, setStoreState] = useState({store});
  useEffect(() => {
    const onChange = () => {
      setStoreState({store});
    }
    store.on('change', onChange);
    return () => {
      store.off('change', onChange);
    }
  }, []);
  return storeState.store;
}

স্টোর এইচওসি হ্যান্ডেল স্টোর আপডেটগুলি

export default function (...stores: SimpleStore[]) {
  return function (WrappedComponent: React.ComponentType<any>) {
    return class WithStore extends PureComponent<{}, {lastUpdated: number}> {
      constructor(props: React.ComponentProps<any>) {
        super(props);
        this.state = {
          lastUpdated: Date.now(),
        };
        this.stores = stores;
      }

      private stores?: SimpleStore[];

      private onChange = () => {
        this.setState({lastUpdated: Date.now()});
      };

      componentDidMount = () => {
        this.stores &&
          this.stores.forEach((store) => {
            // each store has a common change event to subscribe to
            store.on('change', this.onChange);
          });
      };

      componentWillUnmount = () => {
        this.stores &&
          this.stores.forEach((store) => {
            store.off('change', this.onChange);
          });
      };

      render() {
        return (
          <WrappedComponent
            lastUpdated={this.state.lastUpdated}
            {...this.props}
          />
        );
      }
    };
  };
}

সিম্পল স্টোর ক্লাস

import AsyncStorage from '@react-native-community/async-storage';
import ee, {Emitter} from 'event-emitter';

interface SimpleStoreArgs {
  key?: string;
  defaultState?: {[key: string]: any};
}

export default class SimpleStore {
  constructor({key, defaultState}: SimpleStoreArgs) {
    if (key) {
      this.key = key;
      // hydrate here if you want w/ localState or AsyncStorage
    }
    if (defaultState) {
      this._state = {...defaultState, loaded: false};
    } else {
      this._state = {loaded: true};
    }
  }
  protected key: string = '';
  protected _state: {[key: string]: any} = {};
  protected eventEmitter: Emitter = ee({});
  public setState(newState: {[key: string]: any}) {
    this._state = {...this._state, ...newState};
    this.eventEmitter.emit('change');
    if (this.key) {
      // store on client w/ localState or AsyncStorage
    }
  }
  public get state() {
    return this._state;
  }
  public on(ev: string, fn:() => void) {
    this.eventEmitter.on(ev, fn);
  }
  public off(ev: string, fn:() => void) {
    this.eventEmitter.off(ev, fn);
  }
  public get loaded(): boolean {
    return !!this._state.loaded;
  }
}

ব্যবহারবিধি

হুক ক্ষেত্রে:

// use inside function like so
const someState = useStore(myStore);
someState.myProp = 'something';

এইচওসি ক্ষেত্রে:

// inside your code get/set your store and stuff just updates
const val = myStore.myProp;
myOtherStore.myProp = 'something';
// return your wrapped component like so
export default withStores(myStore)(MyComponent);

নিশ্চিত করুন বিশ্বব্যাপী পরিবর্তনের মতো সুবিধা পেতে আপনার স্টোরগুলিকে একক হিসাবে রফতানি করতে:

class MyStore extends SimpleStore {
  public get someProp() {
    return this._state.someProp || '';
  }
  public set someProp(value: string) {
    this.setState({...this._state, someProp: value});
  }
}
// this is a singleton
const myStore = new MyStore();
export {myStore};

এই পদ্ধতিরটি বেশ সহজ এবং আমার পক্ষে কাজ করে। আমি বড় দলগুলিতেও কাজ করি এবং রেডাক্স এবং মবএক্স ব্যবহার করি এবং সেগুলি ভালও পাই তবে কেবল অনেকগুলি বয়লারপ্লেট। আমি ব্যক্তিগতভাবে আমার নিজস্ব পদ্ধতির পছন্দ করি কারণ আমি সর্বদা এমন কোনও কোডের জন্য প্রচুর কোড ঘৃণা করি যা আপনার প্রয়োজন হওয়ার পরে সহজ হতে পারে।


2
আমি মনে করি নিম্নলিখিত হিসাবে পদ্ধতি প্রথম লাইন লিখতে না থাকার আপডেটের পদ্ধতি আপনার দোকানের বর্গ উদাহরণে একটি টাইপো থাকে: this._data = {...this._data, ...newData}
নরবার্ট

2
প্রতিক্রিয়া রচনার পক্ষে উত্তরাধিকারকে নিরুৎসাহিত করে। reactjs.org/docs/composition-vs-inheritance.html
ফ্রেড

1
কেবল স্বচ্ছতা / পঠনযোগ্যতার বিষয়ে ভাবছি, এই.সেটস্টেট (এই.সেটেট) কীভাবে এই.ফোর্স আপডেট () এর চেয়ে ভাল হবে?
জোমন

17

সুতরাং আমি আমার প্রশ্নটি অনুমান করি: প্রতিক্রিয়া দেওয়ার জন্য প্রতিক্রিয়াগুলির উপাদানগুলির কি রাষ্ট্র থাকা দরকার? রাষ্ট্র পরিবর্তন না করে উপাদানটিকে চাহিদার আপডেট করতে বাধ্য করার কোনও উপায় আছে কি?

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

যদি আপনাকে ম্যানুয়ালি জোর করে পুনরায় রেন্ডার করতে হয় তবে আপনি অবশ্যই সঠিক কিছু করছেন না।


@ আর্ট সলোপভ, আপনি কোন সমস্যার কথা উল্লেখ করছেন? কোন ডক্স তাদের উপস্থাপন করে? এবং ধরে নিচ্ছেন যে আপনি রাজ্যে নেস্টেড বস্তুগুলির উল্লেখ করছেন, উত্তরটি হ'ল আপনার রাজ্য সংরক্ষণের জন্য আলাদা কাঠামো ব্যবহার করা। এটি পরিষ্কারভাবে প্রতিক্রিয়ার রাজ্য পরিচালনা করার একটি সর্বোত্তম উপায়। আপনার পৃথকভাবে রাষ্ট্র পরিচালনা করা উচিত নয়। আপনি যদি রাজ্য-ব্যবস্থাপনার সিস্টেমের সাথে কাজ না করেন তবে আপনি প্রতিক্রিয়াটির সবচেয়ে বড় সুবিধা হারাচ্ছেন । ম্যানুয়ালি আপডেটগুলি পরিচালনা করা একটি অ্যান্টি-প্যাটার্ন।
কাইল বেকার

দয়া করে, আপনি এই প্রশ্নটি স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 61277292/ … পরীক্ষা করতে পারেন ?
হুলু ভিকা

4

আপনি এটি বেশ কয়েকটি উপায়ে করতে পারেন:

1. forceUpdate()পদ্ধতিটি ব্যবহার করুন :

forceUpdate()পদ্ধতিটি ব্যবহার করার সময় এমন কিছু সমস্যা রয়েছে happen একটি উদাহরণ হ'ল এটি shouldComponentUpdate()পদ্ধতিটিকে উপেক্ষা করে এবং নির্বিশেষে ভিউটি পুনরায় রেন্ডার করবেshouldComponentUpdate() প্রত্যাবর্তন মিথ্যা । এ কারণে ফোর্সআপডেট () ব্যবহার করা যখন সম্ভব হয় এড়ানো উচিত।

২. এই setState()পদ্ধতিতে পাস করা

নিম্নলিখিত কোডের নীচের লাইনটি পূর্ববর্তী উদাহরণ সহ সমস্যাটি কাটিয়ে উঠেছে:

this.setState(this.state);

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


2
যেহেতু সেটস্টেটটি ব্যাচ করা হয় এটি করা সম্ভবত নিরাপদ:this.setState(prevState => prevState);
মার্ক

1
কেন এটি 'গ্লাচ' তা সত্যই নিশ্চিত নয়। পদ্ধতির নাম ('ফোর্সআপডেট') পরিষ্কার করা যায়নি: আপডেটটি সর্বদা জোর করে।
জোমন

4

আপনার উপাদানটি রেন্ডার করার কয়েকটি উপায় রয়েছে:

সবচেয়ে সহজ সমাধানটি হ'ল ফোর্স আপডেট () পদ্ধতিটি ব্যবহার করা:

this.forceUpdate()

আর একটি সমাধান হ'ল রাজ্যে ব্যবহৃত না চাবি তৈরি করা (ননউসেসকি) এবং এই নন-ইউসেকেডির আপডেটের সাথে সেট স্টেট ফাংশন কল করুন:

this.setState({ nonUsedKey: Date.now() } );

বা সমস্ত বর্তমান অবস্থা আবার লিখুন:

this.setState(this.state);

প্রপস পরিবর্তনগুলি উপাদান পুনরায় সরবরাহকারীও সরবরাহ করে।


3

সম্পূর্ণতার জন্য, আপনি কার্যকরী উপাদানগুলিতে এটি অর্জন করতে পারেন:

const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
// ...
forceUpdate();

বা, পুনরায় ব্যবহারযোগ্য হুক হিসাবে:

const useForceUpdate = () => {
  const [, updateState] = useState();
  return useCallback(() => updateState({}), []);
}
// const forceUpdate = useForceUpdate();

দেখুন: https://stackoverflow.com/a/53215514/2692307

দয়া করে মনে রাখবেন যে জোর-আপডেট প্রক্রিয়াটি ব্যবহার করা এখনও খারাপ অভ্যাস হিসাবে এটি প্রতিক্রিয়াশীল মানসিকতার বিরুদ্ধে যায়, সুতরাং এটি সম্ভব হলে এখনও এড়ানো উচিত।


2

আমরা নিচের মত এটি.ফোর্সআপটেট () ব্যবহার করতে পারি।

       class MyComponent extends React.Component {



      handleButtonClick = ()=>{
          this.forceUpdate();
     }


 render() {

   return (
     <div>
      {Math.random()}
        <button  onClick={this.handleButtonClick}>
        Click me
        </button>
     </div>
    )
  }
}

 ReactDOM.render(<MyComponent /> , mountNode);

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

এখানে সমস্ত উত্তর সঠিকভাবে বোঝার জন্য প্রশ্নের পরিপূরক হয়..আমরা সেট স্টেট ({}) ব্যবহার করে একটি উপাদান পুনরায় রেন্ডার করতে জানি ফোর্সআপেট () ব্যবহার করে।

উপরের কোডটি নীচে হিসাবে সেটস্টেট দিয়ে চলে।

 class MyComponent extends React.Component {



             handleButtonClick = ()=>{
                this.setState({ });
              }


        render() {
         return (
  <div>
    {Math.random()}
    <button  onClick={this.handleButtonClick}>
      Click me
    </button>
  </div>
)
  }
 }

ReactDOM.render(<MyComponent /> , mountNode);

1

গৃহীত উত্তরের ব্যাক-আপের জন্য আর একটি উত্তর :-)

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

এবং যদি আপনি এটি করেন তবে আপনি সম্ভবত জানেন যে পর্যবেক্ষণযোগ্য "অগ্নিকাণ্ডের" সময় আপনাকে পুনরায় রেন্ডার করতে হবে, এবং সুতরাং, আপনি ব্যবহার করা উচিত forceUpdate()এবং এটি আসলে এমন একটি প্লাস যা shouldComponentUpdate()এখানে জড়িত নয়।

মোবএক্স-এর মতো সরঞ্জামগুলি, যা একটি ও-পদ্ধতির গ্রহণ করে, প্রকৃতপক্ষে পৃষ্ঠের নীচে এটি করে চলেছে (আসলে মোবএক্স render()সরাসরি কল করে)


0

ফোর্সআপডেট () এড়ানোর জন্য আমি সবচেয়ে ভাল পেয়েছি। পুনঃ-রেন্ডারকে বাধ্য করার একটি উপায় হ'ল অস্থায়ী বাহ্যিক ভেরিয়েবলের উপর রেন্ডার () এর নির্ভরতা যুক্ত করা এবং যখন প্রয়োজন হয় তখন সেই ভেরিয়েবলের মান পরিবর্তন করা।

এখানে একটি কোড উদাহরণ:

class Example extends Component{
   constructor(props){
      this.state = {temp:0};

      this.forceChange = this.forceChange.bind(this);
   }

   forceChange(){
      this.setState(prevState => ({
          temp: prevState.temp++
      })); 
   }

   render(){
      return(
         <div>{this.state.temp &&
             <div>
                  ... add code here ...
             </div>}
         </div>
      )
   }
}

যখন আপনাকে পুনরায় রেন্ডার করতে বাধ্য করা হবে তখন এটিকে বলুন .ফোর্স চেঞ্জ ()।


0

ES6 - আমি একটি উদাহরণ অন্তর্ভুক্ত করছি, যা আমার জন্য সহায়ক ছিল:

একটি "সংক্ষিপ্ত if বিবৃতি" এ আপনি খালি ফাংশনটি এভাবে পাস করতে পারেন:

isReady ? ()=>{} : onClick

এটি সবচেয়ে সংক্ষিপ্ত পদ্ধতির বলে মনে হচ্ছে।

()=>{}



0

আর একটি উপায় কল করা setState, এবং রাষ্ট্র সংরক্ষণ করুন:

this.setState(prevState=>({...prevState}));


0

ফোর্সআপডেট (), তবে প্রতিবারই আমি যখন কেউ কাউকে এটি সম্পর্কে কথা বলতে শুনেছি, আপনার সাথে এটি অনুসরণ করা হয়েছে কখনই এটি ব্যবহার করা উচিত নয়।


-1

আপনি আরও বিশদ চেক ( ফোর্সআপডেট () ) এর জন্য ফোর্সআপেট () ব্যবহার করতে পারেন ।


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