In my project I have a Page
component, for adding items, and then show them in Navigation
panel:
import React, { useState } from 'react'
const Page = ({setRefreshList}) => {
console.log("PAGE RENDER");
const addItem = () => {
// adding item to database
setRefreshList();
}
return (
<button onClick={addItem}>Add Item</button>
)
}
Navigation
component, with site menu and items:
const Navigation = () => {
console.log("Navigation RENDER");
return (
<div>
List of all items:
</div>
)
}
Some more components in the page, like Header
:
const Header = () => {
console.log("HEADER RENDER");
return (
<div>
HEADER
</div>
)
}
And main App
:
export function App(props) {
const [refreshList, setRefreshList] = useState(0);
return (
<div className='App'>
<Header />
<Navigation />
<Page setRefreshList={setRefreshList} />
</div>
);
}
I need to refresh Navigation
component every time item added in Page
, so I used setState
. Now everytime the state changes, it renders all other components as well.
I tried to use React.memo()
but it has no effect here because props
contains a function. And combining Page
and Navigation
isn't an option, because in the full project they are separate.
Link to online code editor with the example: https://playcode.io/953730/.
CodePudding user response:
"I tried to use React.memo
but it has no effect here because props contains function", well there is a hook for this kind of use cases, called useCallback
, that you can use like this:
const Page = React.memo(({ setRefreshList }) => {
console.log("PAGE RENDER");
const addItem = React.useCallback(() => {
// adding item to database
setRefreshList(Math.random());
}, []);
return <button onClick={addItem}>Add Item</button>;
});
const Navigation = () => {
console.log("Navigation RENDER");
return <div>List of all items:</div>;
};
const Header = React.memo(() => {
console.log("HEADER RENDER");
return <div>HEADER</div>;
});
function App(props) {
const [refreshList, setRefreshList] = React.useState(0);
return (
<div className="App">
<Header />
<Navigation />
<Page setRefreshList={setRefreshList} />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>