Home > Net >  Trigger component render from different component without rendering the whole page
Trigger component render from different component without rendering the whole page

Time:09-03

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>

  • Related