1

I have a question about the correct usage with useEffect and setState in React Hooks.

here is my react app that gets a persisted configuration and some other data depending on the config like this:

function App() {
    const [config, setConfig] = useState(null);
    // some other states 

    useEffect(() => {
        const fetchData = () => {
            axios.get("/path/to/config").then(response => {
                if (response.status === 200) {
                    return response.data
                }
            })
                .then(data => {
                    setConfig(data.config);
                    // set some other states
                })
                .catch(error => {
                    console.log("Error:" + error);
                })
        }
        fetchData();
    }, [config]);

    return (
        <div >
            ...
        </div>
    );
}

If I run this App useEffect is instantly called twice one time for first render and then a second time because setConfig(data.config); is called in the axios get success function.

The user has the possibility to change his own config that is done in another request. If he does I want after state config changes that the config and some other data depending on the config is reloaded via this useEffect function.

Now since there is no setstate callback in react hooks I read somewhere I should use useEffect with the state variable in the dependency array.

How can I prevent that my useEffect is called twice right at the beginning?

I have the feeling that I am doing it all wrong. Thank you in advance

anvin
  • 450
  • 2
  • 8
  • 22

2 Answers2

2

You need to add an if condition in useEffect, because useEffect is called by default on first render.

useEffect(() => {
      if(config !== null){
        const fetchData = () => {
            axios.get("/path/to/config").then(response => {
                if (response.status === 200) {
                    return response.data
                }
            })
                .then(data => {
                    setConfig(data.config);
                    // set some other states
                })
                .catch(error => {
                    console.log("Error:" + error);
                })
        }
        fetchData();
      }
    }, [config]);
Simran Bhake
  • 117
  • 8
  • If I put this if condition into my app the fetchData will not be called since the default value of config is null and this useEffect is the only method that sets config. – anvin Aug 13 '20 at 12:11
  • Oh I see the problem, maybe you can use some other state for useEffect dependency instead of config. Because if you don't want useEffect to be triggered by default on first render then you'll have to use custom hooks or useRef. – Simran Bhake Aug 13 '20 at 12:16
  • I ended up doing that. Thanks for your help! – anvin Aug 14 '20 at 05:53
  • If answer has solved your question please consider [accepting it](https://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – Simran Bhake Aug 14 '20 at 14:28
0

This is not right! I guess this can call fetchData infinitely.

akiradion
  • 1
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 22 '22 at 03:22