admin管理员组文章数量:1022705
I use this pattern sometimes where I declare a curried function inside useCallback
.
const Child = ({ handleClick }) => {
return (
<>
<button onClick={handleClick("foo")}>foo</button>
<button onClick={handleClick("lorem")}>lorem</button>
</>
);
};
export default function App() {
const [state, setState] = useState("");
const handleClick = useCallback(
(newState) => () => {
setState(newState);
},
[]
);
return (
<div className="App">
<Child handleClick={handleClick} />
<p>{state}</p>
</div>
);
}
because I want to pass arguments from JSX to the event handlers and to avoid multiple handlers.
When the ponent rerenders, handleClick
will be called and the function that is returned will be assigned to the onClick
prop, but will it be a new function every time or will the nested function also get memoized by useCallback
?
PS: This is a simple example. Assume a useCallback
usage with multiple dependencies
I use this pattern sometimes where I declare a curried function inside useCallback
.
const Child = ({ handleClick }) => {
return (
<>
<button onClick={handleClick("foo")}>foo</button>
<button onClick={handleClick("lorem")}>lorem</button>
</>
);
};
export default function App() {
const [state, setState] = useState("");
const handleClick = useCallback(
(newState) => () => {
setState(newState);
},
[]
);
return (
<div className="App">
<Child handleClick={handleClick} />
<p>{state}</p>
</div>
);
}
because I want to pass arguments from JSX to the event handlers and to avoid multiple handlers.
When the ponent rerenders, handleClick
will be called and the function that is returned will be assigned to the onClick
prop, but will it be a new function every time or will the nested function also get memoized by useCallback
?
PS: This is a simple example. Assume a useCallback
usage with multiple dependencies
2 Answers
Reset to default 4Edit
Following answer refers to the initial version of the OP's code in which handleClick
was not passed as a prop to Child
ponent.
You don't really need useCallback
in this case.
Actually, it would be better not to use the useCallback
hook in this case because:
Callback function passed to
useCallback
is created everytime your ponent re-renders. As a result, a new function is getting created anyways, just like it would without the use ofuseCallback
Getting a memoized version of the
handleClick
function doesn't provides any benefit in your case. Memoization would be useful ifhandleClick
is passed as a prop to child ponent(s).
...but will it be a new function every time or will the nested function also get memoized by useCallback?
No, the nested function won't be memoized.
handleClick
is a memoized function but that memoized function returns a new function everytime it executes.
Invoking handleClick
is just like invoking any other function - anything declared inside its body is created everytime it is invoked.
It should, either curry or not, it's a function instance, as long as you want to keep an old function instance, you can use it.
But don't use it because the prop onClick
, because when your ponent renders, this button
has to render regardless of the onClick
. So your line can be simply as
const onClick = value => () => { setState(value) }
Or you can even promote this to a global function.
const handle = setState => value => () => { setState(value) }
NOTE: i don't want to say useCallback
most of time is useless. But actually if you don't know why you want to use a useMemo
, don't use a useCallback
. They are designed to skip an assignment, but not designed to skip a render, or in your case, to improve reusability. (not for that purpose).
I use this pattern sometimes where I declare a curried function inside useCallback
.
const Child = ({ handleClick }) => {
return (
<>
<button onClick={handleClick("foo")}>foo</button>
<button onClick={handleClick("lorem")}>lorem</button>
</>
);
};
export default function App() {
const [state, setState] = useState("");
const handleClick = useCallback(
(newState) => () => {
setState(newState);
},
[]
);
return (
<div className="App">
<Child handleClick={handleClick} />
<p>{state}</p>
</div>
);
}
because I want to pass arguments from JSX to the event handlers and to avoid multiple handlers.
When the ponent rerenders, handleClick
will be called and the function that is returned will be assigned to the onClick
prop, but will it be a new function every time or will the nested function also get memoized by useCallback
?
PS: This is a simple example. Assume a useCallback
usage with multiple dependencies
I use this pattern sometimes where I declare a curried function inside useCallback
.
const Child = ({ handleClick }) => {
return (
<>
<button onClick={handleClick("foo")}>foo</button>
<button onClick={handleClick("lorem")}>lorem</button>
</>
);
};
export default function App() {
const [state, setState] = useState("");
const handleClick = useCallback(
(newState) => () => {
setState(newState);
},
[]
);
return (
<div className="App">
<Child handleClick={handleClick} />
<p>{state}</p>
</div>
);
}
because I want to pass arguments from JSX to the event handlers and to avoid multiple handlers.
When the ponent rerenders, handleClick
will be called and the function that is returned will be assigned to the onClick
prop, but will it be a new function every time or will the nested function also get memoized by useCallback
?
PS: This is a simple example. Assume a useCallback
usage with multiple dependencies
2 Answers
Reset to default 4Edit
Following answer refers to the initial version of the OP's code in which handleClick
was not passed as a prop to Child
ponent.
You don't really need useCallback
in this case.
Actually, it would be better not to use the useCallback
hook in this case because:
Callback function passed to
useCallback
is created everytime your ponent re-renders. As a result, a new function is getting created anyways, just like it would without the use ofuseCallback
Getting a memoized version of the
handleClick
function doesn't provides any benefit in your case. Memoization would be useful ifhandleClick
is passed as a prop to child ponent(s).
...but will it be a new function every time or will the nested function also get memoized by useCallback?
No, the nested function won't be memoized.
handleClick
is a memoized function but that memoized function returns a new function everytime it executes.
Invoking handleClick
is just like invoking any other function - anything declared inside its body is created everytime it is invoked.
It should, either curry or not, it's a function instance, as long as you want to keep an old function instance, you can use it.
But don't use it because the prop onClick
, because when your ponent renders, this button
has to render regardless of the onClick
. So your line can be simply as
const onClick = value => () => { setState(value) }
Or you can even promote this to a global function.
const handle = setState => value => () => { setState(value) }
NOTE: i don't want to say useCallback
most of time is useless. But actually if you don't know why you want to use a useMemo
, don't use a useCallback
. They are designed to skip an assignment, but not designed to skip a render, or in your case, to improve reusability. (not for that purpose).
本文标签: javascriptDoes ReactuseCallback memoize curried functionsStack Overflow
版权声明:本文标题:javascript - Does React.useCallback memoize curried functions? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745506098a2153612.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论