I'm converting a React ES6 class-style component to a functional component. The one thing I'm slightly unsure of is how best to convert private class methods. As far as I can tell, I should convert them to functions within the functional component's function, as they need to be there to access the component's state. However, that presumably means that on each re-render, the function is going to get recreated:
Before
class Game extends React.Component {
handleClick(i) { if (this.state.foo) { ... } }
}
After
function Game {
function handleClick(i) { if (foo) { ... } }
}
Is this a problem performance-wise, and if so, is there any way to improve it?
Also, most guides I've read recommend assigning arrow functions to variables instead of just declaring functions, eg.
function Game {
const handleClick = (i) => { if (foo) { ... } }
}
Is this purely stylistic, or is there another reason to use assigned arrow functions over regular nested function definitions?
CodePudding user response:
You can use functions defined with either the function
keyword or the arrow function syntax. It does not really make a difference in this case. However, with the arrow syntax, functions do not get hoisted, and that may cause the linter to report a warning if you use a function before it is defined.
However, that presumably means that on each re-render, the function is going to get recreated
You are correct, if you define functions either way, they will get recreated on every re-render. Whether that's a problem or not will depend on your use case.
If you use such a function inside a useEffect
callback and add it to its dependency array, the effect will re-run on every re-render (which may not be what you want). If you pass such a function as a prop
to any child component(s), that component(s) will also re-render.
You can wrap the functions in question with useCallback
, and any child components that receive these as props
with React.memo
. However, you are now trading the cost of re-rendering components for the cost of storing and comparing props
(React will be doing this, not you).
So really, this depends on your app. If the component in question has a large component tree below it, going with useCallback
and React.memo
might be worth it.