Home > Software engineering >  ReactJS - run once on component mount but before return
ReactJS - run once on component mount but before return

Time:10-30

I am looking to have something run once when the react app first loads and only the one time. At first, one is inclined to make use of the useEffect hook:

  useEffect(() => {
    console.log("Effect hook.");
  }, []); 

The problem with this approach is that when I put it in my App component, the useEffect hook runs AFTER mounting. Subsequently, the following will fail because stuff won't be defined when the child component renders:

function App() {

  let stuff;

  // Define the supported configs on mount. This will only run at mount time.
  useEffect(() => {
    console.log("Effect hook.");
    stuff = getSomeStuff();
  }, []); 

  //

  console.log("About to return.");
  return (
    <div>
      <ComponentThatNeedsStuff stuff={stuff} />
    </div>
  );
}

and you will see the following printed:

About to return.
Effect hook.

If you only want the function getSomeStuff to run once but you need the stuff for child components, what is the best way to handle that?

CodePudding user response:

Running code before render is usually a sign that you’re going against the grain of how React works.

const App = () => {
  const [stuff, setStuff] = useState();

  useEffect(() => {
    console.log("Effect hook.");
    setStuff(getSomeStuff());
  }, []); 


  return (
    <div>
      {stuff && <ComponentThatNeedsStuff stuff={stuff} />}
    </div>
  );
}

CodePudding user response:

This sounds like a job for useMemo. It lets you do a calculation during rendering, but then on later renders it can skip the calculation and reuse the previous value:

function App() {
  const stuff = useMemo(() => {
    return getSomeStuff();
  }, []);

  return (
    <div>
      <ComponentThatNeedsStuff stuff={stuff} />
    </div>
  );
}
  • Related