How to fix WebApp keeps rendering state?












1















I'm setting up a simple weather app using React and Hooks. However, I found out that the app keeps fetching API. How can I stop this?



function WeatherInfo (props) {
const [wind,setWind] = useState(undefined);
const [precipitation,setPrecipitation] = useState(undefined);
const [humidity,setHumidity] = useState(undefined);
const [pressure,setPressure] = useState(undefined);

if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})


}
return (
<div>
{props.city &&
<div>
<p>Wind of {props.city} is {wind}</p>
<p>Chance of rain of {props.city} is {precipitation}%</p>
<p>Humidity of {props.city} is {humidity}</p>
<p>Pressure of {props.city} is {pressure}</p>
</div>
}
</div>
)
}

export default WeatherInfo;


Expect Result: Function only fetchs API once a while










share|improve this question























  • Welcome to SO! I'm not super familiar with react but it looks like you're just showing one component out of context. My guess is there's some state change that's triggering the fetch calls in this component.

    – GenericUser
    Jan 20 at 0:25
















1















I'm setting up a simple weather app using React and Hooks. However, I found out that the app keeps fetching API. How can I stop this?



function WeatherInfo (props) {
const [wind,setWind] = useState(undefined);
const [precipitation,setPrecipitation] = useState(undefined);
const [humidity,setHumidity] = useState(undefined);
const [pressure,setPressure] = useState(undefined);

if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})


}
return (
<div>
{props.city &&
<div>
<p>Wind of {props.city} is {wind}</p>
<p>Chance of rain of {props.city} is {precipitation}%</p>
<p>Humidity of {props.city} is {humidity}</p>
<p>Pressure of {props.city} is {pressure}</p>
</div>
}
</div>
)
}

export default WeatherInfo;


Expect Result: Function only fetchs API once a while










share|improve this question























  • Welcome to SO! I'm not super familiar with react but it looks like you're just showing one component out of context. My guess is there's some state change that's triggering the fetch calls in this component.

    – GenericUser
    Jan 20 at 0:25














1












1








1








I'm setting up a simple weather app using React and Hooks. However, I found out that the app keeps fetching API. How can I stop this?



function WeatherInfo (props) {
const [wind,setWind] = useState(undefined);
const [precipitation,setPrecipitation] = useState(undefined);
const [humidity,setHumidity] = useState(undefined);
const [pressure,setPressure] = useState(undefined);

if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})


}
return (
<div>
{props.city &&
<div>
<p>Wind of {props.city} is {wind}</p>
<p>Chance of rain of {props.city} is {precipitation}%</p>
<p>Humidity of {props.city} is {humidity}</p>
<p>Pressure of {props.city} is {pressure}</p>
</div>
}
</div>
)
}

export default WeatherInfo;


Expect Result: Function only fetchs API once a while










share|improve this question














I'm setting up a simple weather app using React and Hooks. However, I found out that the app keeps fetching API. How can I stop this?



function WeatherInfo (props) {
const [wind,setWind] = useState(undefined);
const [precipitation,setPrecipitation] = useState(undefined);
const [humidity,setHumidity] = useState(undefined);
const [pressure,setPressure] = useState(undefined);

if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})


}
return (
<div>
{props.city &&
<div>
<p>Wind of {props.city} is {wind}</p>
<p>Chance of rain of {props.city} is {precipitation}%</p>
<p>Humidity of {props.city} is {humidity}</p>
<p>Pressure of {props.city} is {pressure}</p>
</div>
}
</div>
)
}

export default WeatherInfo;


Expect Result: Function only fetchs API once a while







reactjs api fetch react-hooks






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 20 at 0:08









ThiiiThiii

82




82













  • Welcome to SO! I'm not super familiar with react but it looks like you're just showing one component out of context. My guess is there's some state change that's triggering the fetch calls in this component.

    – GenericUser
    Jan 20 at 0:25



















  • Welcome to SO! I'm not super familiar with react but it looks like you're just showing one component out of context. My guess is there's some state change that's triggering the fetch calls in this component.

    – GenericUser
    Jan 20 at 0:25

















Welcome to SO! I'm not super familiar with react but it looks like you're just showing one component out of context. My guess is there's some state change that's triggering the fetch calls in this component.

– GenericUser
Jan 20 at 0:25





Welcome to SO! I'm not super familiar with react but it looks like you're just showing one component out of context. My guess is there's some state change that's triggering the fetch calls in this component.

– GenericUser
Jan 20 at 0:25












2 Answers
2






active

oldest

votes


















0














By default, the useEffect hook is run on every rerender. If you don’t want that, you can specify a second optional argument, see https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.



In your specific case: you probably only want to execute the effect when the city changes, so:
useEffect(/* callbacks as before */, [props.city]).



Furthermore, you should only call hooks at the top level (I.e. not in ifs): https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks. You can move the if branching into the callbacks of useEffect






share|improve this answer































    -1














    you could use setInterval to limit how often the code runs like



    setInterval(function(){
    if (props.city) {
    useEffect(() => {
    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
    ).then(data => setWind(data.wind.speed))
    })
    useEffect(() => {
    fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
    ).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
    })
    useEffect(() => {
    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
    ).then(data => setPressure(data.main.pressure))
    })
    useEffect(() => {
    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
    ).then(data => setHumidity(data.main.humidity))
    })}}, 10000);


    then just adjust the time for how often you want it to check






    share|improve this answer
























    • That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

      – inyono
      Jan 20 at 0:45











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54272478%2fhow-to-fix-webapp-keeps-rendering-state%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    By default, the useEffect hook is run on every rerender. If you don’t want that, you can specify a second optional argument, see https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.



    In your specific case: you probably only want to execute the effect when the city changes, so:
    useEffect(/* callbacks as before */, [props.city]).



    Furthermore, you should only call hooks at the top level (I.e. not in ifs): https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks. You can move the if branching into the callbacks of useEffect






    share|improve this answer




























      0














      By default, the useEffect hook is run on every rerender. If you don’t want that, you can specify a second optional argument, see https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.



      In your specific case: you probably only want to execute the effect when the city changes, so:
      useEffect(/* callbacks as before */, [props.city]).



      Furthermore, you should only call hooks at the top level (I.e. not in ifs): https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks. You can move the if branching into the callbacks of useEffect






      share|improve this answer


























        0












        0








        0







        By default, the useEffect hook is run on every rerender. If you don’t want that, you can specify a second optional argument, see https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.



        In your specific case: you probably only want to execute the effect when the city changes, so:
        useEffect(/* callbacks as before */, [props.city]).



        Furthermore, you should only call hooks at the top level (I.e. not in ifs): https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks. You can move the if branching into the callbacks of useEffect






        share|improve this answer













        By default, the useEffect hook is run on every rerender. If you don’t want that, you can specify a second optional argument, see https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.



        In your specific case: you probably only want to execute the effect when the city changes, so:
        useEffect(/* callbacks as before */, [props.city]).



        Furthermore, you should only call hooks at the top level (I.e. not in ifs): https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks. You can move the if branching into the callbacks of useEffect







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 20 at 0:27









        inyonoinyono

        35416




        35416

























            -1














            you could use setInterval to limit how often the code runs like



            setInterval(function(){
            if (props.city) {
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setWind(data.wind.speed))
            })
            useEffect(() => {
            fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
            ).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setPressure(data.main.pressure))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setHumidity(data.main.humidity))
            })}}, 10000);


            then just adjust the time for how often you want it to check






            share|improve this answer
























            • That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

              – inyono
              Jan 20 at 0:45
















            -1














            you could use setInterval to limit how often the code runs like



            setInterval(function(){
            if (props.city) {
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setWind(data.wind.speed))
            })
            useEffect(() => {
            fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
            ).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setPressure(data.main.pressure))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setHumidity(data.main.humidity))
            })}}, 10000);


            then just adjust the time for how often you want it to check






            share|improve this answer
























            • That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

              – inyono
              Jan 20 at 0:45














            -1












            -1








            -1







            you could use setInterval to limit how often the code runs like



            setInterval(function(){
            if (props.city) {
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setWind(data.wind.speed))
            })
            useEffect(() => {
            fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
            ).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setPressure(data.main.pressure))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setHumidity(data.main.humidity))
            })}}, 10000);


            then just adjust the time for how often you want it to check






            share|improve this answer













            you could use setInterval to limit how often the code runs like



            setInterval(function(){
            if (props.city) {
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setWind(data.wind.speed))
            })
            useEffect(() => {
            fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
            ).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setPressure(data.main.pressure))
            })
            useEffect(() => {
            fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
            ).then(data => setHumidity(data.main.humidity))
            })}}, 10000);


            then just adjust the time for how often you want it to check







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 20 at 0:33









            AndreAndre

            1




            1













            • That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

              – inyono
              Jan 20 at 0:45



















            • That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

              – inyono
              Jan 20 at 0:45

















            That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

            – inyono
            Jan 20 at 0:45





            That’s not how React hooks work. They have to be on the top level of the Component to work correctly. So you’d either have to use the native filtering of useEffect,with the second, optional argument or do custom filtering in the useEffect itself.

            – inyono
            Jan 20 at 0:45


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54272478%2fhow-to-fix-webapp-keeps-rendering-state%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Liquibase includeAll doesn't find base path

            How to use setInterval in EJS file?

            Petrus Granier-Deferre