रिएक्ट हुक का उपयोग करते हुए, जब हम किसी फ़ंक्शन के निर्माण को याद रखना चाहते हैं, तो हमारे पास 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>
);
}
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>
);
}
अगर यह मैं होता, तो मैं जितना संभव हो उच्च आदेश समारोह से बच सकता था। इस मामले में, मेरे पास कुछ ऐसा होगा
const MyComponent => ({ dependancies, anArray }) => {
const memoizedFnCreator = useCallback((id, event) => {}, [dependancies]);
return (
<div>
{anArray.map(({ id }) => (
<ChildComponent key={id} onClick={(event) => memoizedFnCreator(id,event)}/>
))}
</div>
);
}
आप जो हासिल करने की कोशिश कर रहे हैं उसके आधार पर, इष्टतम समाधान पूरी तरह से अलग हो सकता है, लेकिन इसके बारे में जाने का एक तरीका यहां दिया गया है:
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>
);
};
चूंकि निर्भरता बदलते ही कैश रीसेट हो जाता है, इसलिए आपके कॉलबैक तदनुसार अपडेट हो जाएंगे।