UseEffect - স্থিতি আপডেট করার সময় অসীম লুপ প্রতিরোধ করুন


9

আমি চাই যে ব্যবহারকারী টোড আইটেমগুলির একটি তালিকা বাছাই করতে সক্ষম হবে। ব্যবহারকারীরা যখন ড্রপডাউন থেকে কোনও আইটেম নির্বাচন করেন এটি সেট করে sortKeyযা এর নতুন সংস্করণ তৈরি করবে এবং ফলস্বরূপ কল এবং কলটি setSortedTodosট্রিগার করবে ।useEffectsetSortedTodos

নীচের উদাহরণটি ঠিক কীভাবে আমি চাই তা কাজ করে তবে এসলিন্ট আমাকে নির্ভরতা অ্যারেতে যুক্ত todosকরতে অনুরোধ জানায় useEffectএবং যদি আমি এটি করি তবে এটি একটি অসীম লুপের কারণ হয় (যেমনটি আপনি আশা করবেন)।

const [todos, setTodos] = useState([]);
const [sortKey, setSortKey] = useState('title');

const setSortedTodos = useCallback((data) => {
  const cloned = data.slice(0);

  const sorted = cloned.sort((a, b) => {
    const v1 = a[sortKey].toLowerCase();
    const v2 = b[sortKey].toLowerCase();

    if (v1 < v2) {
      return -1;
    }

    if (v1 > v2) {
      return 1;
    }

    return 0;
  });

  setTodos(sorted);
}, [sortKey]);

useEffect(() => {
    setSortedTodos(todos);
}, [setSortedTodos]);

সরাসরি উদাহরণ:

আমি ভাবছি এটি করার আরও ভাল উপায় থাকতে হবে যা এস্লিন্টকে খুশি রাখে।


1
কেবলমাত্র একটি পার্শ্ব নোট: sortকলব্যাকটি ঠিক হতে পারে: return a[sortKey].toLowerCase().localeCompare(b[sortKey].toLowerCase());পরিবেশে যুক্তিসঙ্গত লোকেল তথ্য থাকলে লোকাল তুলনা করার সুবিধাও রয়েছে। আপনি যদি পছন্দ করেন তবে এটিতেও কাঠামো
টিজে ক্রাউডার

কি ত্রুটি eslintনিক্ষেপ করা হয়?
লুজ

স্ট্যাক স্নিপেটস ( টুলবার বোতাম) ব্যবহার করে সমস্যার চালানো ন্যূনতম প্রজননযোগ্য উদাহরণ দেওয়ার জন্য আপনি কি প্রশ্নটি আপডেট করতে পারবেন [<>]? স্ট্যাক স্নিপেটস জেএসএক্স সহ প্রতিক্রিয়া সমর্থন করে; এখানে একটি করতে হয় । এইভাবে লোকেরা পরীক্ষা করতে পারবেন যে তাদের প্রস্তাবিত সমাধানগুলিতে অসীম লুপ সমস্যা নেই ...
টিজে ক্রোডার

এটি একটি সত্যই আকর্ষণীয় পদ্ধতির এবং একটি সত্যই আকর্ষণীয় সমস্যা। যেমনটি আপনি বলেছেন, আপনি বুঝতে পারবেন যে কেন এসএসলিন্ট মনে করেন যে আপনাকে todosনির্ভরতা অ্যারেতে যুক্ত করা দরকার useEffectএবং আপনি কেন তা করবেন না তা দেখতে পারেন। :-)
টিজে ক্রাউডার

আমি আপনার জন্য লাইভ উদাহরণ যোগ। সত্যিই এই উত্তর দেখতে চান।
টিজে ক্রাউডার

উত্তর:


8

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

আপনি কেন সাজানো অ্যারে রাজ্যে রাখবেন না কেন? useMemoকী বা অ্যারের পরিবর্তিত হলে আপনি মানগুলি বাছাই করতে ব্যবহার করতে পারেন:

const sortedTodos = useMemo(() => {
  return Array.from(todos).sort((a, b) => {
    const v1 = a[sortKey].toLowerCase();
    const v2 = b[sortKey].toLowerCase();

    if (v1 < v2) {
      return -1;
    }

    if (v1 > v2) {
      return 1;
    }

    return 0;
  });
}, [sortKey, todos]);

তারপরে sortedTodosসর্বত্র রেফারেন্স দিন ।

সরাসরি উদাহরণ:

বাছাই করা মানগুলিকে স্টেটে রাখার দরকার নেই, যেহেতু আপনি সর্বদা "বেস" অ্যারে এবং বাছাই কী থেকে বাছাই করা অ্যারে গণনা / অঙ্কন করতে পারেন। আমি যুক্তি দিচ্ছি যে এটি আপনার কোডটি কম জটিল হওয়ায় এটি বোঝা সহজ করে তোলে।


ওহ সুন্দর ব্যবহার useMemo। শুধু একটি পার্শ্ব-প্রশ্ন, বাছাই কেন ব্যবহার করবেন .localCompareনা?
টিক্কস

2
এটা আসলে ভাল হবে। আমি কেবল ওপি কোডটি অনুলিপি করেছি এবং তাতে মনোযোগ দিই নি (সমস্যার সাথে সত্যই প্রাসঙ্গিক নয়)।
ফেলিক্স ক্লিং

সত্যিই সহজ, সহজে বোঝার সমাধান।
টিজে ক্রাউডার

আহা, ইউমেমো! সে সম্পর্কে ভুলে
গিয়েছি

3

অসীম লুপের কারণ হ'ল টডস আগের রেফারেন্সের সাথে মেলে না এবং প্রভাবটি আবার চালু হবে।

ক্লিক-অ্যাকশনের জন্য যাইহোক কেন একটি প্রভাব ব্যবহার করবেন? আপনি এটিকে এভাবে কোনও ফাংশনে চালাতে পারেন:

const [todos, setTodos] = useState([]);

function sortTodos(e) {
    const sortKey = e.target.value;
    const clonedTodos = [...todos];
    const sorted = clonedTodos.sort((a, b) => {
        return a[sortKey.toLowerCase()].localeCompare(b[sortKey.toLowerCase()]);
    });

    setTodos(sorted);
}

এবং আপনার ড্রপডাউন একটি করতে onChange

    <select onChange="sortTodos"> ......

উপায় দ্বারা নির্ভরতার উপর নোট করুন, ESLint ঠিক! আপনার টোডোস, উপরে বর্ণিত ক্ষেত্রে একটি নির্ভরতা এবং তালিকায় থাকা উচিত। কোনও আইটেম নির্বাচনের পদ্ধতিটি ভুল, এবং সেইজন্য আপনার সমস্যা।


2
"সাজানোর ফলে অ্যারের নতুন উদাহরণ ফিরে আসবে" বিল্ট-ইন বাছাইয়ের পদ্ধতি নয়। এটি জায়গায় অ্যারে বাছাই করে। data.slice(0)অনুলিপি তৈরি করে।
ফেলিক্স ক্লিং

এটি সত্য নয় যখন আপনি setStateএটি করেন যেহেতু এটি বিদ্যমান অবজেক্টটি সম্পাদনা করবে না এবং এর জন্য এটি অভ্যন্তরীণভাবে এটি ক্লোন করবে। আমার উত্তরে ভুল কথা বলা, সত্য। আমি এটি সম্পাদনা করব।
টিক্কেস

setStateডেটা ক্লোন করে না। কেন তোমার এটা মনে হল?
ফেলিক্স ক্লিং

1
@ টিক্কস - না, setStateকিছুই ক্লোন করে না। ফেলিক্স এবং ওপি সঠিক, আপনার বাছাইয়ের আগে অ্যারেটি অনুলিপি করতে হবে।
টিজে ক্রাউডার

ঠিক আছে হ্যাঁ, দুঃখিত। আমার মনে হয় ইন্টারনালগুলিতে আরও কিছু পড়া দরকার। আপনাকে অবশ্যই অনুলিপি করতে হবে এবং বিদ্যমানটি পরিবর্তন করতে হবে না state
টিক্কস

0

আপনার এখানে যা করতে হবে তা হ'ল কার্যকরী ফর্মটি ব্যবহার করা setState:

  const [todos, setTodos] = useState(exampleToDos);
    const [sortKey, setSortKey] = useState('title');

    const setSortedTodos = useCallback((data) => {

      setTodos(currTodos => {
        return currTodos.sort((a, b) => {
          const v1 = a[sortKey].toLowerCase();
          const v2 = b[sortKey].toLowerCase();

          if (v1 < v2) {
            return -1;
          }

          if (v1 > v2) {
            return 1;
          }

          return 0;
        });
      })

    }, [sortKey]);

    useEffect(() => {
        setSortedTodos(todos);
    }, [setSortedTodos, todos]);

ওয়ার্কিং কোডস্যান্ডবক্স

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

কার্যকরী ব্যবহার setStateনিশ্চিত করে যে আপনি রাজ্যের সর্বশেষ মান পাবেন এবং মূল রাষ্ট্রীয় মানটিকে পরিবর্তন করবেন না।


"এবং মূল রাষ্ট্রীয় মানটি পরিবর্তন করবেন না" " আমি মনে করি না প্রতিক্রিয়া কলব্যাকটিতে একটি অনুলিপি দেয়। .sortঅ্যারেটিকে স্থানে পরিবর্তন করে দেয় তাই আপনার নিজের এটি অনুলিপি করতে হবে।
ফেলিক্স ক্লিং

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

এটি এখানে পাওয়া গেছে: reactjs.org/docs/… । 'আমরা সেটস্টেটের কার্যকরী আপডেট ফর্মটি ব্যবহার করতে পারি। এটি আমাদের বর্তমান রাষ্ট্রকে উল্লেখ না করে কীভাবে রাজ্যটির পরিবর্তন দরকার তা নির্দিষ্ট করতে দেয় '
স্পষ্টতা

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