简体   繁体   中英

Unable to set response data in my local state using hooks in react

I am using Functional components and am a beginner.I am receiving the response from API successfully but when I am setting it to the local useState variable, it still remains empty.I am unable to understand how to fix this.

Approach 1:

const [sites,setSites]=useState([]);
useEffect(()=>{
    getAllSites().then(res=>{
      console.log("res",res.sites);//response received successfully
      setSites(res.sites);
      console.log(sites);//return empty array
    })
    .catch(err=>{
      console.log("Error:",err);
    })
  },[])

Approach 2:

const [sites,setSites]=useState([]);
useEffect(()=>{
    getAllSites().then(res=>{
      console.log("res",res.sites);
    },(res)=>{
     setSites(res);//thought maybe because of async nature, so tried using callback but still empty 
})
    .catch(err=>{
      console.log("Error:",err);
    })
  },[])

Can someone help me out with this?

Updating state in react will not happen synchronously. That means when you call setSites the state will not get updated then and there rather the changes or the updated state will be available in the next render.

In order to see if that is working or not, we can make use of useEffect hook by passing the state variable as dependency

 const {useState, useEffect} = React; const getAllSites = () => { return new Promise(res => { setTimeout(() => { return res({sites:[{id:1, name:"Google"}, {id:2, name:"Facebook"}]}); }, 500) }) } const App = () => { const [sites,setSites] = useState([]); useEffect(()=>{ getAllSites().then(res=>{ //console.log("res",res.sites);//response received successfully setSites(res.sites); }).catch(err=>{ console.log("Error:",err); }) },[]); useEffect(() => { //This will print on mount as well as when there's any change in `sites` console.log(sites); }, [sites]) return <p>App</p> } ReactDOM.render(<App />, document.getElementById("react"));
 <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="react"></div>

And, while the data is being fetched you can display the loading indication and once the data is available you can hide loading and display the actual data.

You are doing everything correct. But you cannot see immediately updated value in the sites (obviously it is const) so you will see on the next render cycle, when your functional component will be run and react will assign new value to the sites. Once state updated new rerendering will happen. Just add console.log(sites) to the top level of your functional component

const [sites,setSites]=useState([]);
console.log(sites);
useEffect(()=>{...},[]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM