When sending props to a PureComponent
or a functional component, you can optimize performance by using props that don't change for every render, which will prevent the component from re-rendering.
When using class components this is simple:
class Component extends React.Component {
render() {
return <List createRows={this.createRows}/>;
}
createRows = () => this.props.data.map(dataToRow);
}
Given List
being either a PureCompoment
or a functional component, the createRows
prop will never cause a re-render of List
.
But if the Component
is a functional component, this is no longer possible:
function Component(props) {
return <List createRows={createRows}/>;
function createRows() {
return props.data.map(dataToRow);
}
}
Since createRows
is created every time Component
renders, the prop will change, causing a re-render of List
every time Component
is re-rendered. This can cause a big loss in performance. Notice also that the createRows
cannot be placed outside the functional component, since it is dependent on the data
prop of List
.
Now, with the introduction on Hooks, it is possible to hold the createRows
in a useState
hook:
function Component(props) {
const [ createRows ] = useState(() => () =>
props.data.map(dataToRow);
);
return <List createRows={createRows}/>;
}
Since the createRows
is saved in a state hook, it will not change with each render, and no re-render of List
will occour, like we want.
However, this seems more like a hack than a solution.
What is best practice for sending a function prop from a functional components to a child component, without causing unnecessary re-renders of the child component?
useCallback
hook exists exactly to solve this problem. I advise you to carefully read the official guide to hooks, it pretty much answers all possible questions
function Component(props) {
const createRows = useCallback(() =>
props.data.map(dataToRow);
), []); // provide dependencies here
return <List createRows={createRows}/>;
}
This is the purpose of useCallback
. You can find more details in some of my related answers below.
Trouble with simple example of React Hooks useCallback
What is the intension of using React's useCallback hook in place of useEffect?
React Hooks useCallback causes child to re-render
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With