Monday, May 13, 2024
 Popular · Latest · Hot · Upcoming
-1
rated 0 times [  1] [ 2]  / answers: 1 / hits: 5125  / 4 Years ago, fri, january 24, 2020, 12:00:00

When passing a callback function, especially when passing a parameterized function, I know that I should use the useCallback hook because the use of anonymous functions can adversely affect performance.



the example of anonymous function I said is like this.



import React, { useState } from 'react';

const Component = () => {
const [param, setParam] = useState('');
...

return (
...
<SomeComponent
onClick={() => setParam('parameter')}
{...others}
/>
);
}


In the process of converting an anonymous function to use this hook, I encountered an error saying 'Too many renders' or it didn't work properly.
But I don't know exactly in what situation and in what situation.



and I used useCallback like below.



import React, { useState, useCallback } from 'react';

const Component = () => {
const [param, setParam] = useState('');

const handleClick = useCallback((params) => {
setParam(params);
},[]);

...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
}


However, when using an anonymous function to return within useCallback, it also worked.



This means code like here. (Only the differences compared to the code above.)



  const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);


In this situation, I wonder if it's worse than just using an anonymous function inside the useCallback if I simply use an anonymous function instead of using this hook.


More From » reactjs

 Answers
4
  const handleClick = useCallback((params) => {
setParam(params);
},[]);

...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);


in the above code during first render, at this statement onClick={handleClick('parameter')} handleClick function is called with a string named parameter. since handleClick has setParam(parameter), it will update state. updating state will cause re-render which will again come to same statement onClick={handleClick('parameter')} causing infinte loop.



following code you added later works because you are not updating state, instead returning a function, which acts as onclick handler.



const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);


better way of doing this shoud be as follwing,



import React, { useState, useCallback } from 'react';

const Component = () => {
const [param, setParam] = useState('');

const handleClick = useCallback((params) => {
setParam(params);
},[]);

...
return (
...
<SomeComponent
onClick={handleClick}
{...others}
/>
);
}


coming back to your question , comparing performance depends on the other function definitions and render times of child compoents inside return function inside your Compoenent.
let's say you have another onclickHanldier named 'anotherHandleClick' inside your app.
then your component looks like this



const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');

const handleClick = (params) => {
setParam(params);
};
const anotherHandleClick =(params) => {
setAnotherParam(params);
};
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}


in the above component when any one of SomeCompoenent clicked entiere Component re-renders, so the handler functions are newly defined.and when both 's does referential equality check on onclick handler functions, they believe it is new handler function which casues them to render both.
in that case it is better to use useCallBack hook as following,



const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');

const handleClick = useCallback((params) => {
setParam(params);
},[]);
const anotherHandleClick = useCallback((params) => {
setAnotherParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}


in the above code when any one is clicked , state changes. then when rendering, useCallback make sure that onclick handler refernces didn't change. so having dependency of onclick handlers won't be rerendered.



so final thought is It's creating a function on each render in both cases. the second (because it'e wrapped in a useCallback) will return the memoized function created on the initial render



when to use useMemo or useCallback refer this


[#4956] Wednesday, January 22, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
alli

Total Points: 409
Total Questions: 101
Total Answers: 105

Location: The Bahamas
Member since Tue, Apr 27, 2021
3 Years ago
alli questions
Sat, Apr 23, 22, 00:00, 2 Years ago
Mon, May 18, 20, 00:00, 4 Years ago
Tue, Mar 24, 20, 00:00, 4 Years ago
;