रिएक्ट हुक का उपयोग करते हुए, जब हम किसी फ़ंक्शन के निर्माण को याद रखना चाहते हैं, तो हमारे पास useCallback हुक होता है। ताकि हमारे पास हो:

const MyComponent = ({ dependancies }) => {
  const memoizedFn = useCallback(() => { 
    /* ... */ 
  }, [dependancies]);

  return <ChildComponent onClick={memoizedFn} />;
}

मेरा प्रश्न यह है कि, हम useCallback हुक में एक उच्च क्रम फ़ंक्शन के मानों को कैसे याद करते हैं जैसे:

const MyComponent => ({ dependancies, anArray }) => {
  const memoizedFnCreator = useCallback((id) => () => {
    /* ... */
  }, [dependancies]);

  /* 
   * How do we make sure calling "memoizedFnCreator" does not result in
   * the ChildComponent rerendering due to a new function being created?
   */
  return (
    <div>
      {anArray.map(({ id }) => (
         <ChildComponent key={id} onClick={memoizedFnCreator(id)} />
      ))}
    </div>
  );
}
2
codingedward 19 अक्टूबर 2020, 14:41

3 जवाब

सबसे बढ़िया उत्तर

HoC में "क्रिएटर-फ़ंक्शन" पास करने के बजाय आप एक फ़ंक्शन को पास कर सकते हैं जो तर्क के रूप में id लेता है और ChildComponent को अपना क्लिक हैंडलर बनाने देता है

नीचे दिए गए कोड उदाहरण में ध्यान दें कि onClick में MyComponent अब एक अद्वितीय फ़ंक्शन नहीं बनाता है, लेकिन सभी मैप किए गए तत्वों में एक ही फ़ंक्शन का पुन: उपयोग करता है, हालांकि ChildComponent एक अद्वितीय फ़ंक्शन बनाता है।

const ChildComponent = ({ itemId, onClick }) => {
    // Create a onClick handler  when calls `onClick` with the item's id
    const handleClick = useCallback(() => {
        onClick(itemId)
    }, [onClick, itemId])

    return <button onClick={handleClick}>Click me</button>
}

const MyComponent = ({ dependancies, anArray }) => {
    // Memoize a function which takes in the id and performs some action
    const handleItemClick = useCallback((id) => {
        /* ... */
    }, [dependancies]);

    return (
        <div>
            {anArray.map(({ id }) => (
                <ChildComponent key={id} itemId={id} onClick={handleItemClick} />
            ))}
        </div>
    );
}
3
TryingToImprove 19 अक्टूबर 2020, 16:20

अगर यह मैं होता, तो मैं जितना संभव हो उच्च आदेश समारोह से बच सकता था। इस मामले में, मेरे पास कुछ ऐसा होगा

const MyComponent => ({ dependancies, anArray }) => {
  const memoizedFnCreator = useCallback((id, event) => {}, [dependancies]);
  return (
    <div>
      {anArray.map(({ id }) => (
         <ChildComponent key={id} onClick={(event) => memoizedFnCreator(id,event)}/>
      ))}
    </div>
  );
}
1
Kevin Koech 19 अक्टूबर 2020, 16:14

आप जो हासिल करने की कोशिश कर रहे हैं उसके आधार पर, इष्टतम समाधान पूरी तरह से अलग हो सकता है, लेकिन इसके बारे में जाने का एक तरीका यहां दिया गया है:

const MyComponent = ({ dependencies, array }) => {
  // create a memoized callbacks cache, where we will store callbacks.
  // This cache will reset every time dependencies change.
  const callbacks = useMemo(() => ({}), [dependencies]);

  const createCallback = useCallback(
    id => {
      if (!callbacks[id]) {
        // Cache the callback here...
        callbacks[id] = () => {
          /* ... */
        };
      }
      // ...and return it.
      return callbacks[id];
    },
    [dependencies, callbacks]
  );

  return (
    <div>
      {array.map(({ id }) => (
        <ChildComponent key={id} onClick={createCallback(id)} />
      ))}
    </div>
  );
};

चूंकि निर्भरता बदलते ही कैश रीसेट हो जाता है, इसलिए आपके कॉलबैक तदनुसार अपडेट हो जाएंगे।

1
Avius 19 अक्टूबर 2020, 16:27