ব্যবহারের প্রভাব প্রতিক্রিয়া হুক ব্যবহার করার সময় কীভাবে নিখোঁজ নির্ভরতা সতর্কতা ঠিক করবেন?


174

১ 16.৮..6 এর প্রতিক্রিয়া সহ (এটি পূর্ববর্তী সংস্করণ 16.8.3 এ ভাল ছিল), যখন আমি আনার অনুরোধে অসীম লুপটি রোধ করার চেষ্টা করি তখন আমি এই ত্রুটিটি পাই

./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

আমি এমন কোনও সমাধান খুঁজে পাইনি যা অসীম লুপ বন্ধ করে দেয়। আমি ব্যবহার থেকে দূরে থাকতে চাই useReducer()। আমি এই আলোচনাটি https://github.com/facebook/react/issues/14920 পেয়েছি যেখানে সম্ভাব্য সমাধান হ'ল You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.আমি যা করছি তা নিয়ে আমি আত্মবিশ্বাসী নই আমি এখনও এটি বাস্তবায়নের চেষ্টা করিনি।

আমার এই বর্তমান সেটআপ প্রতিক্রিয়া হুক ব্যবহারের প্রভাবটি চিরতরে / অসীম লুপ অব্যাহত থাকে এবং একমাত্র মন্তব্যটি useCallback()যার সাথে আমি পরিচিত নই।

আমি বর্তমানে কীভাবে ব্যবহার করছি useEffect()(যা আমি প্রথমদিকে একইভাবে একবার চালাতে চাই componentDidMount())

useEffect(() => {
    fetchBusinesses();
  }, []);
const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };

উত্তর:


189

আপনি যদি প্রভাবটি বাদে অন্য কোথাও ফেচব্যাজনেস পদ্ধতি ব্যবহার না করে থাকেন তবে আপনি এটিকে কার্যকরভাবে স্থানান্তর করতে এবং সতর্কতা এড়াতে পারবেন

useEffect(() => {
    const fetchBusinesses = () => {
       return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
  fetchBusinesses();
}, []);

তবে আপনি যদি রেন্ডারের বাইরে ফেচব্যাশনগুলি ব্যবহার করেন তবে আপনার অবশ্যই দুটি জিনিস নোট করতে হবে

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

সংক্ষেপে আমি বলব যে আপনি যদি fetchBusinessesবাইরে বাইরে ব্যবহার করেন useEffectতবে নিয়মটি ব্যবহার করে অক্ষম করতে পারেন// eslint-disable-next-line react-hooks/exhaustive-deps করতে পারেন অন্যথায় আপনি পদ্ধতিটি ব্যবহারের অভ্যন্তরে সরিয়ে নিতে পারেন

নিয়মটি অক্ষম করতে আপনি এটি লিখতে পছন্দ করেন

useEffect(() => {
   // other code
   ...

   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 

14
আপনার সমাধানটি আমি সুন্দরভাবে বর্ণিত করেছি। অন্য একটি সমাধান যা আমি অন্যত্র ব্যবহার করেছি যেখানে ভিন্ন সেটআপের কারণে ছিল useCallback()। সুতরাং উদাহরণস্বরূপ: const fetchBusinesses= useCallback(() => { ... }, [...]) এবং এর useEffect()মত দেখতে হবে:useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);
russ করুন

1
@ আরস, আপনি সঠিক, আপনি যদি নির্ভরতা অ্যারেতে পাস করতে চান তবে ব্যবহারের কলব্যাক ব্যবহার করে স্মৃতিচারণ করতে হবে
শুভম খত্রি ২ '

ভাল হবে যদি আপনি দেখান যেখানে এস্লিন্ট-অক্ষম বিবরণী রাখা হয়। আমি ভেবেছিলাম এটি ব্যবহারের উপরে থাকবে
ব্যবহারকারীর 210757

1
ব্যবহার // eslint-disable-next-line react-hooks/exhaustive-depsLinter ব্যাখ্যা করা জরুরী যে আপনার কোড সঠিক একটি হ্যাক ভালো হয়। আমি আশা করি যে কোনও যুক্তি বাধ্যতামূলক নয় তখন তারা লণ্ঠনকে আরও চৌর্য করে তুলতে আরও একটি সমাধান খুঁজে পাবে
অলিভিয়ার বোইস

1
@ ট্যাপাসাধিকারী, হ্যাঁ আপনি ইউজএফেক্টে একটি অ্যাসিঙ্ক ফাংশন রাখতে পারেন, আপনাকে এটি আলাদাভাবে লিখতে হবে। দয়া করে স্ট্যাকওভারফ্লো.com
শুভম খত্রি

75
./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

এটি জেএস / প্রতিক্রিয়া ত্রুটি নয় তবে এসলিন্ট (এসলিন্ট-প্লাগ-ইন-রিঅ্যাক্ট-হুকস) সতর্কতা।

এটি আপনাকে বলছে যে হুক ফাংশনের উপর নির্ভর করে fetchBusinessesতাই আপনার এটি নির্ভরতা হিসাবে পাস করা উচিত।

useEffect(() => {
  fetchBusinesses();
}, [fetchBusinesses]);

যদি ফাংশনটির মতো উপাদানগুলিতে ঘোষিত হয় তবে এটি প্রতিটি রেন্ডার ফাংশনটির ফলাফল করতে পারে:

const Component = () => {
  /*...*/

  //new function declaration every render
  const fetchBusinesses = () => {
    fetch('/api/businesses/')
      .then(...)
  }

  useEffect(() => {
    fetchBusinesses();
  }, [fetchBusinesses]);

  /*...*/
}

কারণ প্রতিটি সময় ফাংশনটি নতুন রেফারেন্স সহ পুনরায় ঘোষিত হয়

এই জিনিসগুলি করার সঠিক উপায় হ'ল:

const Component = () => {
  /*...*/

  // keep function reference
  const fetchBusinesses = useCallback(() => {
    fetch('/api/businesses/')
      .then(...)
  }, [/* additional dependencies */]) 

  useEffect(() => {
    fetchBusinesses();
  }, [fetchBusinesses]);

  /*...*/
}

বা শুধু মধ্যে ফাংশন সংজ্ঞায়িত useEffect

আরও: https://github.com/facebook/react/issues/14920


13
একটি নতুন ত্রুটির মাধ্যমে এই ফলাফলLine 20: The 'fetchBusinesses' function makes the dependencies of useEffect Hook (at line 51) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'fetchBusinesses' definition into its own useCallback() Hook
Russ

1
সমাধানটি ঠিক আছে এবং যদি ফাংশনটিতে আপনি অন্য একটি রাষ্ট্র পরিবর্তন করেন তবে আপনাকে অন্য একটি অপ্রত্যাশিত আচরণ এড়াতে নির্ভর করতে হবে
সিজারারসনসন

54

আপনি এটিকে সরাসরি useEffectকলব্যাক হিসাবে সেট করতে পারেন :

useEffect(fetchBusinesses, [])

এটি কেবল একবার ট্রিগার করবে, সুতরাং নিশ্চিত হয়ে নিন যে সমস্ত ফাংশনের নির্ভরতা সঠিকভাবে সেট করা আছে (ব্যবহারের মতো componentDidMount/componentWillMount...)


02/21/2020 সম্পাদনা করুন

কেবল সম্পূর্ণতার জন্য:

1. useEffectকলব্যাক হিসাবে ফাংশন ব্যবহার করুন (উপরে হিসাবে)

useEffect(fetchBusinesses, [])

2. ভিতরে ফাংশন ঘোষণা useEffect()

useEffect(() => {
  function fetchBusinesses() {
    ...
  }
  fetchBusinesses()
}, [])

3. সাথে স্মরণ করা useCallback()

এই ক্ষেত্রে যদি আপনার ফাংশনে নির্ভরতা থাকে তবে আপনাকে সেগুলি useCallbackনির্ভরতা অ্যারেতে অন্তর্ভুক্ত করতে হবে এবং useEffectযদি ফাংশনের প্যারামগুলি পরিবর্তন হয় তবে এটি আবার ট্রিগার করবে । এছাড়াও এটি অনেকগুলি বয়লারপ্লেট ... সুতরাং কেবলমাত্র ফাংশনটি সরাসরি useEffectহিসাবে প্রবেশ করুন 1. useEffect(fetchBusinesses, [])

const fetchBusinesses = useCallback(() => {
  ...
}, [])
useEffect(() => {
  fetchBusinesses()
}, [fetchBusinesses])

4. এসলিন্টের সতর্কতা অক্ষম করুন

useEffect(() => {
  fetchBusinesses()
}, []) // eslint-disable-line react-hooks/exhaustive-deps

2
আমি তোমাকে ভালবাসি ... এই উত্তরটি সম্পূর্ণ!
নিক ০৯

8

সমাধানটি প্রতিক্রিয়া দ্বারা দেওয়া হয়, তারা আপনাকে ব্যবহার করার পরামর্শ দেয় useCallbackযা আপনার ফাংশনের একটি স্মৃতি সংস্করণ ফিরিয়ে দেবে:

'ফেচব্যাজনেস' ফাংশন প্রতিটি রেন্ডারে ব্যবহারের প্রভাবের হুক (লাইন এনএন) এর নির্ভরতাগুলিকে পরিবর্তন করে। এটি ঠিক করার জন্য, 'ফেচব্যাশনস' সংজ্ঞাটিকে তার নিজের ব্যবহারের মধ্যে আবদ্ধ করুন ক্যালব্যাক () হুক প্রতিক্রিয়া-হুক / এক্সেসিউটিভ-ডিপস

useCallbackuseEffectপার্থক্য হ'ল এটি ব্যবহার করতে সহজ কারণ পার্থক্যটি হ'ল একই রকম স্বাক্ষর যেমন ইউজক্যালব্যাক একটি ফাংশন দেয়। এটি দেখতে এটি দেখতে হবে:

 const fetchBusinesses = useCallback( () => {
        return fetch("theURL", {method: "GET"}
    )
    .then(() => { /* some stuff */ })
    .catch(() => { /* some error handling */ })
  }, [/* deps */])
  // We have a first effect thant uses fetchBusinesses
  useEffect(() => {
    // do things and then fetchBusinesses
    fetchBusinesses(); 
  }, [fetchBusinesses]);
   // We can have many effect thant uses fetchBusinesses
  useEffect(() => {
    // do other things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);

2

এই সতর্কবার্তা উপাদান যে ধারাবাহিকভাবে আপডেট করে না খোঁজার জন্য খুবই সহায়ক আছেন: https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- নির্ভরতা

তবে, আপনি যদি আপনার প্রকল্প জুড়ে সতর্কতাগুলি সরাতে চান তবে আপনি এটি আপনার এসলিন্ট কনফিগারেশনে যুক্ত করতে পারেন:

  {
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/exhaustive-deps": 0
    }
  }

1

এই নিবন্ধটি হুক সহ ডেটা আনার জন্য একটি ভাল প্রাইমার: https://www.robinwieruch.de/react-hooks-fetch-data/

মূলত, ভিতরে আনতে ফাংশন সংজ্ঞা অন্তর্ভুক্ত করুন useEffect:

useEffect(() => {
  const fetchBusinesses = () => {
    return fetch("theUrl"...
      // ...your fetch implementation
    );
  }

  fetchBusinesses();
}, []);

1

আপনি ২ য় আর্গুমেন্ট ধরণের অ্যারে সরিয়ে ফেলতে পারেন []তবে fetchBusinesses()প্রতি আপডেটটিও ডাকা হবে। আপনি চাইলে বাস্তবায়নে একটি IFবিবৃতি যুক্ত fetchBusinesses()করতে পারেন।

React.useEffect(() => {
  fetchBusinesses();
});

অন্যটি হ'ল fetchBusinesses()আপনার উপাদানগুলির বাইরে ফাংশনটি বাস্তবায়ন করা । আপনার fetchBusinesses(dependency)কলটিতে কোনও নির্ভরতার যুক্তিগুলি ভুলে যাবেন না , যদি থাকে তবে।

function fetchBusinesses (fetch) {
  return fetch("theURL", { method: "GET" })
    .then(res => normalizeResponseErrors(res))
    .then(res => res.json())
    .then(rcvdBusinesses => {
      // some stuff
    })
    .catch(err => {
      // some error handling
    });
}

function YourComponent (props) {
  const { fetch } = props;

  React.useEffect(() => {
    fetchBusinesses(fetch);
  }, [fetch]);

  // ...
}

0

হুকস দিয়ে বিকাশ করার সময় আসলে সতর্কতাগুলি খুব কার্যকর। তবে কিছু ক্ষেত্রে এটি আপনাকে সুই করতে পারে। বিশেষত যখন নির্ভরতা পরিবর্তনের জন্য আপনাকে শুনতে হবে না।

আপনি যদি fetchBusinessesহুকের নির্ভরতার ভিতরে রাখতে না চান , আপনি কেবল এটি হুকের কলব্যাকের পক্ষে যুক্তি হিসাবে পাস করতে পারেন এবং এর জন্য মূলটিকে fetchBusinessesডিফল্ট মান হিসাবে সেট করতে পারেন you

useEffect((fetchBusinesses = fetchBusinesses) => {
   fetchBusinesses();
}, []);

এটি সর্বোত্তম অনুশীলন নয় তবে এটি কিছু ক্ষেত্রে কার্যকর হতে পারে।

শুভনাম যেমন লিখেছেন, আপনি ESLint কে আপনার হুকের জন্য চেক করা উপেক্ষা করার জন্য নীচের কোড যুক্ত করতে পারেন।

// eslint-disable-next-line react-hooks/exhaustive-deps

0

আমি কেবল একবারে শুরু করতে চাই [ fetchBusinesses] একবারের মতোcomponentDidMount()

আপনি fetchBusinessesআপনার উপাদান থেকে পুরোপুরি টানতে পারেন :

const fetchBusinesses = () => { // or pass some additional input from component as args
  return fetch("theURL", { method: "GET" }).then(n => process(n));
};

const Comp = () => {
  React.useEffect(() => {
    fetchBusinesses().then(someVal => {
      // ... do something with someVal
    });
  }, []); // eslint warning solved!
  return <div>{state}</div>;
};

এটি কেবল একটি সহজ সমাধান সরবরাহ করবে না এবং সম্পূর্ণ-এক্সেস সতর্কতা সমাধান করবে solve fetchBusinessএখন আরও ভাল পরীক্ষা করা যায় এবং সহজ হয়ে যায়Comp , কারণ এটি প্রতিক্রিয়া গাছের বাইরে মডিউল স্কোপে থাকে।

Relocating fetchBusinessesবাহিরে কাজ ভাল এখানে, আমরা কেবল পড়তে সক্ষম হবে যেমন প্রাথমিক মামুলি অবসান সুযোগ (কারণে উপাদান যাহাই হউক না কেন থেকে সাজসরঞ্জাম এবং রাষ্ট্র []মধ্যে Dép useEffect)।

কীভাবে ফাংশন নির্ভরতা বাদ দেওয়া যায়

  • কার্যকারিতা ভিতরে ফাংশন সরান
  • উপাদানটির বাইরে ফাংশন সরান - (আমরা এটি ব্যবহার করছি)
  • রেন্ডারিংয়ের সময় কল করুন এবং useEffectএই মানটির উপর নির্ভর করুন (খাঁটি গণনা ফাংশন)
  • ডিপগুলি কার্যকর করতে ফাংশনটি যুক্ত করুন এবং এটি useCallbackসর্বশেষ রিসোর্ট হিসাবে মোড়ানো করুন

অন্যান্য সমাধান সম্পর্কিত:

যদি আপনি এটিতে অন্য রাজ্যে অ্যাক্সেস করেন তবে fetchBusinessesভিতরে টান useEffect()আসলেই সহায়তা করে না। এসলিন্টটি এখনও অভিযোগ করবে: কোডস্যান্ডবক্স

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


0
const [mount, setMount] = useState(false)
const fetchBusinesses = () => { 
   //function defination
}
useEffect(() => {
   if(!mount) {
      setMount(true);
      fetchBusinesses();
   }
},[fetchBusinesses]);

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


0

আপনি এইভাবে চেষ্টা করুন

const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };

এবং

useEffect(() => {
    fetchBusinesses();
  });

এটা তোমার জন্য কাজ তবে আমার পরামর্শটি এইভাবে চেষ্টা করা আপনার পক্ষেও কাজ করে। এটা আগের চেয়ে ভাল। আমি এইভাবে ব্যবহার করি:

useEffect(() => {
        const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
        fetchBusinesses();
      }, []);

যদি আপনি নির্দিষ্ট আইডির ভিত্তিতে ডেটা পান [id]তবে কলব্যাক ইউজএফেক্ট যুক্ত করুন তবে আপনাকে সতর্কতা প্রদর্শন করতে পারবেন না React Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array


-4

কেবল পরের লাইনের জন্য এসিলিন্ট অক্ষম করুন;

useEffect(() => {
   fetchBusinesses();
// eslint-disable-next-line
}, []);

এইভাবে আপনি এটি কোনও উপাদান যেমন মাউন্ট করেছেন (যেমন একবার বলা হয়) ঠিক তেমন ব্যবহার করছেন

আপডেট

অথবা

const fetchBusinesses = useCallback(() => {
 // your logic in here
 }, [someDeps])

useEffect(() => {
   fetchBusinesses();
// no need to skip eslint warning
}, [fetchBusinesses]); 

ফেচব্যাশনগুলিকে প্রতিবার ডেকে পাঠানো হবে কিছু ডেপস পরিবর্তন হবে


অক্ষম করার পরিবর্তে, কেবল এটি করা: [fetchBusinesses]স্বয়ংক্রিয়ভাবে সতর্কতাটি সরিয়ে ফেলবে এবং এটি আমার জন্য সমস্যাটি সমাধান করেছে।
রোটিমি-সেরা

7
@ রোটিমিবেস্ট - এটি করা প্রশ্নে বর্ণিত হিসাবে অসীম পুনরায় রেন্ডার কারণ
ব্যবহারকারী 210757

কিছুক্ষণ আগে আমি আমার প্রকল্পের একটিতে এইভাবে এটি করেছি এবং এটি অসীম লুপ তৈরি করে নি। যদিও আমি আবার চেক করব।
রোটিমি-সেরা

@ user210757 অপেক্ষা করুন তবে কেন এটি অসীম লুপ তৈরি করবে, এটি সার্ভার থেকে ডেটা আনার পরে আপনি রাষ্ট্রটি সেট করছেন এমন নয়। আপনি যদি রাষ্ট্র আপডেট করে useEffectথাকেন তবে রাষ্ট্রটি খালি আছে কিনা তা পরীক্ষা করে ফাংশনটি কল করার আগে কেবল শর্তটি লিখুন ।
রোটিমি সেরা

@ রোটিমি সেরা হওয়ার সাথে সাথে আমি মন্তব্য করেছি তবে আমি বলব যে ফাংশনটি প্রতিবার পুনরায় তৈরি করা হয়েছে তাই এর আগে কখনও হয় না তাই সর্বদা পুনরায় রেন্ডার হবে না, যদি না আপনি ব্যবহারের পদক্ষেপে বা ব্যবহারের কলব্যাকে না চলে যান
user210757 ২
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.