Reputation: 755
I have a React component, Activity, with a DataTable and a Drawer (from Material UI). I set whether the Drawer is open based on the isDrawerOpen
property the Activity component's state. However, when isDrawerOpen
is updated, Activity, Drawer, and DataTable all rerender.
I don't want DataTable
to rerender because nothing has changed. I have tried to use React.memo
and I've tried useEffect
in conjunction with useRef
in my DataTable functional component to not rerender if the props are the same. It's not working. How can I prevent this child component from rerendering when none of its props change?
const Activity = props => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [tableData, setTableData] = useState(["banana", "orange", "apple"]);
return (
<div>
<DataTable data={tableData} onRowClick={() => setIsDrawerOpen(true) } />
<Drawer open={isDrawerOpen}>Some Drawer Content </Drawer>
</div>
)
}
Upvotes: 16
Views: 9713
Reputation: 44880
Something actually is changing though... it's constructing a new function on each render for onRowClick
, which then forces the child to re-render because it gets new props. This is what the useCallback
hook is for:
const Activity = props => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [tableData, setTableData] = useState(["banana", "orange", "apple"]);
// Because `setIsDrawerOpen` never changes across renders, it's safe to
// pass an empty deps array as the second argument.
const onRowClick = useCallback(() => setIsDrawerOpen(true), []);
return (
<div>
<DataTable data={tableData} onRowClick={onRowClick} />
<Drawer open={isDrawerOpen}>Some Drawer Content </Drawer>
</div>
);
}
Upvotes: 12