If you only want to run the function given to useEffect after the initial render, you can give it an empty array as second argument.

function MyComponent() {
  useEffect(() => {
    loadDataOnlyOnce();
  }, []);

  return <div> {/* ... */} </div>;
}
Answer from Tholle on Stack Overflow
🌐
React
legacy.reactjs.org › docs › hooks-effect.html
Using the Effect Hook – React
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run.
People also ask

How does the dependency array affect the useEffect hook's execution?
The dependency array controls when the effect is re-invoked; React will only re-run the effect if any value in the dependency array changes, allowing for precise control over component side effects.
🌐
dhiwise.com
dhiwise.com › post › how-to-make-useeffect-run-only-once-for-optimal
How to Make useEffect Run Only Once for React
How can you skip the useEffect execution on the first render?
Skipping useEffect on the first render can be achieved by employing strategies like memoizing the effect function with the useCallback hook, ensuring it runs only on subsequent renders.
🌐
dhiwise.com
dhiwise.com › post › how-to-make-useeffect-run-only-once-for-optimal
How to Make useEffect Run Only Once for React
What is the purpose of passing an empty array to useEffect?
Passing an empty array as the second argument to useEffect tells React to run the effect only once after the initial render, optimizing performance for component mounts.
🌐
dhiwise.com
dhiwise.com › post › how-to-make-useeffect-run-only-once-for-optimal
How to Make useEffect Run Only Once for React
🌐
Reddit
reddit.com › r/reactjs › what is the best way to execute a piece of code just once when the component mounts?
r/reactjs on Reddit: What is the best way to execute a piece of code just once when the component mounts?
January 26, 2024 -

Lets take an example - I want to initialize the SDK of a partner who will be loading an iframe on my page

  1. I can use a `useEffect` with empty dependency array. It will work fine in production but will be fired twice in development mode. And that does not feel right

  2. I can use `useRef` and base my logic around it, But this does not look intuitive either.

What would be the best way to do this?

🌐
React
react.dev › reference › react › useEffect
useEffect – React
See common solutions. Try to write every Effect as an independent process and think about a single setup/cleanup cycle at a time. It shouldn’t matter whether your component is mounting, updating, or unmounting.
🌐
Reddit
reddit.com › r/reactjs › why is this useeffect hook called?
r/reactjs on Reddit: why is this useEffect hook called?
March 28, 2024 -
const TestComponent = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);

useEffect(() => {
    console.log("Only run if isLoggedIn changes");
}, [isLoggedIn]);

return (
    <div>
        <h1>Test Component</h1>
    </div>
);

};

export default TestComponent;

surely it's only meant to execute when isLoggedIn changes?

Find elsewhere
Top answer
1 of 12
300

You can use more than one useEffect().

For example, if my variable is data1, I can use all of this in my component:

useEffect( () => console.log("mount"), [] );
useEffect( () => console.log("data1 update"), [ data1 ] );
useEffect( () => console.log("any update") );
useEffect( () => () => console.log("data1 update or unmount"), [ data1 ] );
useEffect( () => () => console.log("unmount"), [] );
2 of 12
166

Since the cleanup is not dependent on the username, you could put the cleanup in a separate useEffect that is given an empty array as second argument.

Example

const { useState, useEffect } = React;

const ForExample = () => {
  const [name, setName] = useState("");
  const [username, setUsername] = useState("");

  useEffect(
    () => {
      console.log("effect");
    },
    [username]
  );

  useEffect(() => {
    return () => {
      console.log("cleaned up");
    };
  }, []);

  const handleName = e => {
    const { value } = e.target;

    setName(value);
  };

  const handleUsername = e => {
    const { value } = e.target;

    setUsername(value);
  };

  return (
    <div>
      <div>
        <input value={name} onChange={handleName} />
        <input value={username} onChange={handleUsername} />
      </div>
      <div>
        <div>
          <span>{name}</span>
        </div>
        <div>
          <span>{username}</span>
        </div>
      </div>
    </div>
  );
};

function App() {
  const [shouldRender, setShouldRender] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setShouldRender(false);
    }, 5000);
  }, []);

  return shouldRender ? <ForExample /> : null;
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

🌐
DEV Community
dev.to › esedev › useeffect-vs-useeffectonce-2cnk
useEffect vs useEffectOnce - DEV Community
March 8, 2023 - It then calls useEffect with the same callback and an empty array as the second argument, which tells React to only execute the callback once, after the initial render. Here's an example of how to use useEffectOnce to initialize a third-party ...
🌐
DhiWise
dhiwise.com › post › how-to-make-useeffect-run-only-once-for-optimal
How to Make useEffect Run Only Once for React
October 25, 2024 - To ensure that useEffect runs only once and mimics the behavior of componentDidMount, you can pass an empty array as the second argument. Passing an empty array ensures the effect runs only once during the initial render cycle.
🌐
Perssondennis
perssondennis.com › articles › react-hook-use-run-once
Persson Dennis - React Hook: useRunOnce | Web Development Blog
July 17, 2022 - React hook useRunOnce. A React hook to run code once on mount, or once per session. Easy way to run code only once in a React functional component.
🌐
Robin Wieruch
robinwieruch.de › react-useeffect-only-once
React useEffect only Once - Robin Wieruch
November 7, 2020 - import * as React from 'react'; const App = () => { const [toggle, setToggle] = React.useState(true); const handleToggle = () => { setToggle(!toggle); }; const calledOnce = React.useRef(false); React.useEffect(() => { if (calledOnce.current) { return; } if (toggle === false) { console.log('I run only once if toggle is false.'); calledOnce.current = true; } }, [toggle]); return ( <div> <button type="button" onClick={handleToggle}> Toggle </button> {toggle && <div>Hello React</div>} </div> ); }; export default App; If you want to have a reusable custom hook for it, which only triggers the effect function once (and not on mount), you can use the following hook for it:
🌐
TypeOfNaN
typeofnan.dev › how-to-prevent-useeffect-from-running-on-mount-in-react
How to prevent useEffect from running on mount in React | TypeOfNaN
In this case, we’ll create a ref to a boolean that tracks whether the component has mounted. It will start out as false, but once the effect runs for the first time, we can change it to true.
🌐
Josh Software
blog.joshsoftware.com › 2021 › 08 › 09 › react-tricks-customizing-your-useeffect-to-run-only-when-you-want
React Tricks: Customizing your useEffect to run ONLY when you want! – Josh Software
July 22, 2022 - If you want to run an effect only on mount, and the effect depends on a stateful variable, all you need to do is declare the useEffect without that variable in the dependency array.
🌐
DEV Community
dev.to › cassidoo › when-useeffect-runs-3pf3
When useEffect runs - DEV Community
June 4, 2024 - So, you set it to true when the component mounts, and then whenever syncWithMe changes, the effect function is called. Because of how the new Suspense functionality works and a bunch of other changes that happened in React 18, useEffect needs to be manipulated more to run just once in development and strict mode (it should be fine in production but eh, this is still worth talking about).
Top answer
1 of 3
19

There are a couple of things there. First, to fix the code, you could update your useEffect to this:

useEffect(() => {
    messagesRef.on('child added', snapshot => {
    const message = snapshot.val();
    message.key = snapshot.key;

    setMessages(messages.concat(message)); // See Note 1
}, []); // See Note 2

Note 1

The setMessages line is how you update your state. useState is a little bit different from the "old" setState in a sense that will completely replace the state value. React documentation says:

This is because when we update a state variable, we replace its value. This is different from this.setState in a class, which merges the updated fields into the object.

Note 2

React Hooks changes the way we build apps and it is not a real "translation" from the old lifecycles.

The empty brackets ([]) in the last line, will make your code "similar" to componentDidMount, but most importantly, will make your effect run only once.

Dan Abramov said (removed some of the original text):

While you can useEffect(fn, []), it’s not an exact equivalent. Unlike componentDidMount, it will capture props and state. So even inside the callbacks, you’ll see the initial props and state. (...) Keep in mind that the mental model for effects is different from componentDidMount and other lifecycles, and trying to find their exact equivalents may confuse you more than help. To get productive, you need to “think in effects”, and their mental model is closer to implementing synchronization than to responding to lifecycle events.

Full article about useEffect here.

2 of 3
1

You tried to declare the state again instead of using the state updater

useEffect(() => {
  messagesRef.on('child added', snapshot => {
    const message = snapshot.val();
    message.key = snapshot.key;
    // setMessages is the state updater for messages
    // instead of an object with messages: messagesArray
    // just save it as an array the name is already messages
    setMessages([...messages, message]);
  });
// useEffect takes an array as second argument with the dependencies
// of the effect, if one of the dependencies changes the effect will rerun
// provide an empty array if you want to run this effect only on mount
}, []);
🌐
CSS-Tricks
css-tricks.com › run-useeffect-only-once
Run useEffect Only Once | CSS-Tricks
July 30, 2019 - Also, to get componentDidMount, ... parameter to useEffect. To run componentWillUnmount just once, you return a cleanup function from useEffect and pass an empty array as the second parameter too....
🌐
Medium
medium.com › @taraparakj75 › https-bosctechlabs-com-how-to-call-loading-function-with-react-useeffect-only-once-4d1700126bd1
How to call loading function with React useEffect only once | by Kuldeep Tarapara | Medium
May 1, 2024 - Bypassing the second argument, ... calling Callback after the first render. Running a function only once after the component mounts for a pattern justifies a react hook practices....
🌐
Dave Ceddia
daveceddia.com › useeffect-hook-examples
How the useEffect Hook Works (with Examples)
If you’ve never touched classes and never intend to, you can disregard the comparison to lifecycles – but this section will still be useful for learning when useEffect runs and how it fits into React’s render cycle. Let’s look at how to run code after a component mounts (componentDidMount), after it re-renders (componentDidUpdate), and before it unmounts (componentWillUnmount).
🌐
DEV Community
dev.to › ssharish › run-useeffect-only-once-react-57go
Run useEffect Only Once :React - DEV Community
February 13, 2020 - If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run.