আমি কি একটি ব্যবহারের প্রভাবের হুকের মধ্যে স্থিতি স্থাপন করতে পারি?


115

আসুন বলুন যে আমার কিছু রাজ্য রয়েছে যা অন্য কোনও রাজ্যের উপর নির্ভরশীল (যেমন যখন আমি যখন বি পরিবর্তন করতে চাই তখন পরিবর্তন হয়)।

এটি এমন একটি হুক তৈরি করা উপযুক্ত যা এ পর্যবেক্ষণ করে এবং ব্যবহারের প্রভাবের হুকের ভিতরে বি সেট করে?

প্রভাবগুলি কী ক্যাসকেড করবে, যখন আমি বোতামটি ক্লিক করব, তখন প্রথম প্রভাবটি আগুন লাগবে, ফলে বি পরিবর্তিত হবে, দ্বিতীয় প্রভাবটি আগুনে লাগবে, পরবর্তী রেন্ডার করার আগে? স্ট্রাকচারিং কোডের মতো কোনও পারফরম্যান্স ডাউনসাইড রয়েছে?

let MyComponent = props => {
  let [a, setA] = useState(1)
  let [b, setB] = useState(2)
  useEffect(
    () => {
      if (/*some stuff is true*/) {
        setB(3)
      }
    },
    [a],
  )
  useEffect(
    () => {
      // do some stuff
    },
    [b],
  )

  return (
    <button
      onClick={() => {
        setA(5)
      }}
    >
      click me
    </button>
  )
}

উত্তর:


32

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

যে bকারণে আপনি changing aএকই যুক্তিটি কার্যকর করতে চান এমন ক্ষেত্রে ছাড়া অন্য কারণগুলির কারণে পরিবর্তিত হতে পারে এমন সম্ভাবনা না থাকলে উভয় পদক্ষেপকে একইভাবে কার্যকর করা তার পক্ষে আরও ভাল said


4
সুতরাং যদি A পরিবর্তন করে বি, কম্পোনেন্টটি দ্বিগুণ রেন্ডার করবে?
ড্যান রসউইক

4
আমি উপরের প্রশ্নের উত্তরও জানতে চাই
আলাবৌদি

4
@ আলাবৌদি হ্যাঁ, যদি এমন কোনও পরিবর্তন ঘটে যা ব্যবহারকারীকে কার্যকর করে দেয় যা বি সেট করে তবে উপাদানটি দু'বার রেন্ডার হয়
শুভম খাতরী

95

সাধারণভাবে বলতে গেলে, setStateভিতরে ব্যবহার করেuseEffect এমন একটি অসীম লুপ তৈরি হবে যা সম্ভবত আপনি তৈরি করতে চান না। সেই নিয়মের ক্ষেত্রে বেশ কয়েকটি ব্যতিক্রম রয়েছে যা আমি পরে নিয়ে যাব।

useEffectপ্রতিটি রেন্ডারের পরে ডাকা হয় এবং এর অভ্যন্তরে যখন setStateএটি ব্যবহার করা হয়, তখন এটি উপাদানটিকে পুনরায় রেন্ডার করতে দেয় যা কল করবে useEffectএবং এ জাতীয় কিছু।

জনপ্রিয় মামলা হল যে ব্যবহার useStateভেতরে useEffectএকটি অসীম লুপ কারণ হবে না হয় যখন আপনি একটি দ্বিতীয় আর্গুমেন্ট হিসাবে একটি খালি অ্যারে পাস useEffectমত useEffect(() => {....}, [])যার মানে প্রভাব ফাংশন একবার বলে অভিহিত হই প্রথম মাউন্ট / শুধুমাত্র রেন্ডার। আপনি যখন কোনও উপাদানগুলিতে ডেটা আনছেন তখন এটি ব্যাপকভাবে ব্যবহৃত হয় এবং আপনি উপাদানটির রাজ্যে অনুরোধের ডেটা সংরক্ষণ করতে চান।


4
ব্যবহার করতে অন্য ক্ষেত্রে setStateভিতরে useEffectহয় setting stateসাবস্ক্রিপশন বা ঘটনা শ্রোতাকে ভিতরে। তবে সাবস্ক্রিপশনটি বাতিল করতে ভুলবেন না reactjs.org/docs/hooks-effect.html#effects-with-cleanup
টিমকিয়ান

30
এটি কঠোরভাবে সত্য নয় - আপনি যখন স্টেটটি আপডেট করছেন তার মানটি আগেরটির চেয়ে আলাদা হয় তবে চক্রের মধ্যে মান পরিবর্তিত হলে অসীম লুপ প্রতিরোধ করা হয় তবে ইউজস্টেটটি কেবল আগুনে ছড়িয়ে পড়ে।
রবএম

14
এই উত্তরটি ভুল এবং প্রশ্নের বিন্দুতে নয়: ক্ষেত্রে কোডে, উপাদানটি কেবল দু'বার রেন্ডার করে যখন বোতামটি ক্লিক করা হয়, কোনও অসীম লুপ নেই
বোগদান ডি

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

4
আপনি উল্লিখিত সমস্যাগুলির সমাধানের জন্য উত্তরটি আপডেট করেছি, এখন কি এটি আরও ভাল?
হোসাম মুরাদ

50

ভবিষ্যতের উদ্দেশ্যে, এটি খুব সাহায্য করতে পারে:

সেটস্টেট ইন ব্যবহার করা ঠিক আছে useEffectআপনার আছে কোনও লুপ তৈরি না করার জন্য ইতিমধ্যে বর্ণিত হিসাবে মনোযোগ দেওয়া দরকার।

তবে এটিই কেবল সমস্যা হতে পারে না। নিচে দেখ:

কল্পনা করুন যে আপনার কাছে এমন একটি উপাদান রয়েছে Compযা propsপিতামাতার কাছ থেকে প্রাপ্ত হয় এবং propsপরিবর্তনের অনুসারে আপনি Compতার রাজ্য সেট করতে চান । কিছু কারণে, আপনার প্রতিটি প্রপকে আলাদাভাবে পরিবর্তন করতে হবে useEffect:

এটা করো না

useEffect(() => {
  setState({ ...state, a: props.a });
}, [props.a]);

useEffect(() => {
  setState({ ...state, b: props.b });
}, [props.b]);

এটি উদাহরণের মতো দেখতে পারা যায় না এমন অবস্থার কোনও পরিবর্তন হতে পারে না: https://codesandbox.io/s/confident-lederberg-dtx7w

কারণ এই এই উদাহরণে ঘটতে ইহার কারণ উভয় useEffects একই চালানোর চক্র প্রতিক্রিয়া যখন আপনি পরিবর্তন উভয় prop.aএবং prop.bতাই এর মান {...state}যখন আপনি কি setStateঠিক উভয় একই useEffectকারণ তারা একই প্রেক্ষাপটে হয়। আপনি যখন দ্বিতীয়টি চালাবেন setStateএটি প্রথমটি প্রতিস্থাপন করবেsetState

এই ইনস্টল করুন

এই সমস্যার সমাধানটি মূলত এইভাবে কল করা হয় setState:

useEffect(() => {
  setState(state => ({ ...state, a: props.a }));
}, [props.a]);

useEffect(() => {
  setState(state => ({ ...state, b: props.b }));
}, [props.b]);

সমাধানটি এখানে দেখুন: https://codesandbox.io/s/mutable-surf-nynlx

আপনি যখন এগিয়ে যান তখন আপনি সর্বদা রাষ্ট্রের সর্বাধিক আপডেট হওয়া এবং সঠিক মান পাবেন setState

আমি আশা করি এটা কারো সাহায্যে লাগবে!


4
উপরের সমাধানটি আমাকে সহায়তা করেছেsetName(name => ({ ...name, a: props.a }));
mufaddal_mw

4
এটি আমাকে তীর ফাংশনটির অংশেও সহায়তা করেছিলsetItems(items => [...items, item])
স্টিফান lyেলিয়াজকভ

বাহ, আপনি দুর্দান্ত আপনি আজ আমার একটি * সংরক্ষণ করেছেন।
প্রতীক সনি

সমাধান না করে সকাল AM টা থেকে ৩ টা অবধি ব্যয় করুন এবং এখন আপনি আমাকে বাঁচিয়েছেন।
দিনিন্ডু কাঞ্চনা

21

useEffectএকটি নির্দিষ্ট প্রপ বা রাজ্য হুক করতে পারেন। সুতরাং, অসীম লুপ হুক এড়ানোর জন্য আপনার যে জিনিসটি করা দরকার তা হ'ল কিছু পরিবর্তনশীল বা স্থিতি কার্যকর করতে বাধ্য

উদাহরণ স্বরূপ:

useEffect(myeffectCallback, [])

উপরের প্রভাবটি কেবল একবার সরবরাহ করা হবে। এটি componentDidMountলাইফাইসাইকেলের অনুরূপ

const [something, setSomething] = withState(0)
const [myState, setMyState] = withState(0)
useEffect(() => {
  setSomething(0)
}, myState)

উপরের প্রভাবটি কেবল আগুনে ছড়িয়ে দেবে কেবলমাত্র আমার রাষ্ট্র পরিবর্তিত হয়েছে এটি পরিবর্তনের পরিবর্তে componentDidUpdateপ্রতিটি পরিবর্তনকারী রাষ্ট্রই এটি জ্বালিয়ে দেবে না।

আপনি এই লিঙ্কটি যদিও আরও বিস্তারিত পড়তে পারেন


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

10

? 1. আমি কি ব্যবহারের প্রভাবের হুকের ভিতরে রাজ্যটি সেট করতে পারি?

বস্তুত, আপনি রাষ্ট্র অবাধে সেট করতে পারেন যেখানে আপনি এটি প্রয়োজন - ভিতরে সহ useEffectএবং এমনকি রেন্ডারিং সময় । হুককে depsসঠিকভাবে এবং / অথবা শর্তাধীন স্থিতি দিয়ে অসীম লুপগুলি এড়ানো নিশ্চিত করুন ।


▶ 2. বলুন যে আমার কিছু রাজ্য রয়েছে যা অন্য কোনও রাজ্যের উপর নির্ভরশীল। এটি এমন একটি হুক তৈরি করা উপযুক্ত যা এ পর্যবেক্ষণ করে এবং ব্যবহারের প্রভাবের হুকের ভিতরে বি সেট করে?

আপনি কেবল ক্লাসিক ব্যবহারের ক্ষেত্রে এর জন্য বর্ণনা করেছেনuseReducer :

useReduceruseStateযখন আপনার কাছে জটিল রাষ্ট্র যুক্তি থাকে যা একাধিক উপ-মানগুলিতে জড়িত থাকে বা যখন পরবর্তী রাজ্যটি পূর্বেরটির উপর নির্ভর করে তখন সাধারণত তার চেয়ে ভাল । ( দস্তাবেজের প্রতিক্রিয়া )

যখন কোনও রাষ্ট্রের ভেরিয়েবল সেট করা হয় তখন অন্য রাষ্ট্রের ভেরিয়েবলের বর্তমান মানের উপর নির্ভর করে , আপনি তাদের উভয়কে প্রতিস্থাপনের চেষ্টা করতে চাইতে পারেন । [...] আপনি যখন নিজেকে লেখার বিষয়টি খুঁজে পান , তার পরিবর্তে একটি হ্রাসকারী ব্যবহার করার জন্য এটি ভাল সময় time ( ড্যান আব্রামভ, অত্যুক্তি করা ব্লগ )useReducer setSomething(something => ...)


? 3. প্রভাবগুলি কী ক্যাসকেড করবে, যখন আমি বোতামটি ক্লিক করব, তখন প্রথম প্রভাবটি আগুন লাগবে, ফলে বি পরিবর্তিত হবে, দ্বিতীয় প্রভাবটি পরবর্তী রেন্ডার করার আগে আগুনে ফেলেছে?

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


? 4. স্ট্রাকচারিং কোডের মতো কোনও পারফরম্যান্স ডাউনসাইডস কি আছে?

হ্যাঁ. অবস্থা পরিবর্তন মোড়কে bএকটি পৃথক মধ্যে useEffectজন্য a, ব্রাউজার একটি অতিরিক্ত বিন্যাস / পেইন্ট ফেজ আছে - এইসব প্রভাব সম্ভাব্য ব্যবহারকারীর জন্য দৃশ্যমান। আপনি যদি useReducerচেষ্টা করার কোনও উপায় না পান তবে আপনি সরাসরি bএকসাথে রাষ্ট্র পরিবর্তন করতে পারেন a:

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