I want to ask. Where should I define function in React stateless component?
For example:
I want to prepare function to call it with some parameters, but I want to avoid create new one after re-render.
Pseudocode:
const example = (params) => {...}
const statelessComponent = () => {
return(
<button onClick={example(params)}
)
}
or
const statelessComponent = () => {
const example = (params) => {...}
return(
<button onClick={example(params)}
)
}
but I also want to avoid:
- calling function while render
- I don't want to use "useCallback" hook to prevent create new reference.
If only one solution is to create function in Parent component and send it via props to Children component and after that call this function ?
Can someone explain me, how to do it with the best performance without useCallback or useMemo hooks?
Thank you.
I want to ask. Where should I define function in React stateless component?
For example:
I want to prepare function to call it with some parameters, but I want to avoid create new one after re-render.
Pseudocode:
const example = (params) => {...}
const statelessComponent = () => {
return(
<button onClick={example(params)}
)
}
or
const statelessComponent = () => {
const example = (params) => {...}
return(
<button onClick={example(params)}
)
}
but I also want to avoid:
- calling function while render
- I don't want to use "useCallback" hook to prevent create new reference.
If only one solution is to create function in Parent component and send it via props to Children component and after that call this function ?
Can someone explain me, how to do it with the best performance without useCallback or useMemo hooks?
Thank you.
Share Improve this question asked Nov 11, 2019 at 21:15 frontreactfrontreact 2693 silver badges3 bronze badges 3- 1 Possible duplicate of Functions in stateless components? – jmargolisvt Commented Nov 11, 2019 at 21:20
- why dont you want useCallback? – duc mai Commented Nov 11, 2019 at 21:23
- 1 I assume it must be a bit more performant to define the subsidiary function outside the component, but it's hard to imagine this would ever make much practical difference. If the subsidiary function is only ever used in this one component I would define it in the (function) component's scope, due to general software design principles. – Robin Zigmond Commented Nov 11, 2019 at 21:26
1 Answer
Reset to default 172021 edit:
After implementation of React Hooks, the issue is no longer relevant - you can declare functions inside your functional component as long as you want. However if you want to avoid children re-render, you can wrap your functions with useCallback
hook so the function instance remains between renders.
const handleChange = useCallback(() => /* do stuff */, []);
https://reactjs.org/docs/hooks-reference.html#usecallback
Old answer:
I would suggest to keep your functions outside the Stateless Components as long as it's possible.
Consider following example. Your parent component re-renders, so the SFC child does (FYI: SFC re-renders everytime parent re-renders, it doesn't have any built-in shallow props comparison logic).
If you declare function inside SFC, it will create a completely new instance with every re-render.
If you declare function outside SFC, it will be used n-times, but the function itself will remain the same instance.
Working example at StackBlitz: https://stackblitz.com/edit/react-1m2hds
How to test it - write something inside input, then click on the child. Parent will re-render, so the child does. The outside-box function fn1
gets pushed to window variable test1
, the inside-box function fn2
goes into test2
. Now repeat process. If you compare functions inside test1
-> test1[0] === test1[1]
will return true
, since both of the functions are the same instance.
If you compare test2[0] === test2[1]
it will return false
, because new instance of function was created.
Note: Use built-in StackBlitz console for testing purposes.
Final note: regardless of what been told above, the perfomance differences are basically unnoticeable.
window.test1 = [];
window.test2 = [];
class App extends Component {
state = {
name: 'React'
};
handleChange = (e) => this.setState({ name: e.target.value });
render() {
return (
<div>
<Child name={this.state.name} />
</div>
);
}
}
const fn1 = () => {};
const Child = ({ name }) => {
const fn2 = () => {};
const checkout = () => {
window.test1.push(fn1);
window.test2.push(fn2);
}
return (
<div onClick={checkout}>{name}</div>
);
}