Fetching API data with React

Maks

So I'm trying to fetch data from my API and I'm able to log it into console, but I can't render it into my app using useState. Tried something like that and it completely ignores my h2.

var id = "61bf209bdb079818ec63d9fd";

const Main = () => {
    const [name, setName] = useState("");
    const [fromApi, setFromApi] = useState([]);
    
    const getApiData = () => {
        fetch('http://localhost:3000/myapi')
            .then(res => {
                return res.json();
            })
            .then(data => {
                console.log(data);
                setFromApi(data);
            })
        
        for (var i = 0; i < fromApi.length; i++) {
            if (fromApi[i]._id === id) {
                setName(fromApi[i].name);
            }
        }
    }

    useEffect(() => {
        getApiData();
    }, [])
    
    return (
        <div>
            {name && <h2 className='urname'>Your name: {name}</h2>}
        </div>
    )
}
Sanket Shah

This is happening because React does not guarantee that the state changes are applied immediately. This makes reading state right after updating (in your case setFromApi) a potential pitfall and can potentially return the existing value due to async nature.

React Doc: https://reactjs.org/docs/react-component.html?#setstate

In your case you're using data receiving from API and running for loop even before fromAPI state gets updated. Instead put fromAPI in dependency array to useEffect and perform your for loop there.

var id = "61bf209bdb079818ec63d9fd";

const Main = () => {
    const [name, setName] = useState("");
    const [fromApi, setFromApi] = useState([]);
    
    const getApiData = () => {
        fetch('http://localhost:3000/myapi')
            .then(res => {
                return res.json();
            })
            .then(data => {
                console.log(data);
                setFromApi(data);
            })
    }

    useEffect(() => {
        getApiData();
    }, [])

    useEffect(() => {
      if(fromApi?.length){
        for (var i = 0; i < fromApi.length; i++) {
            if (fromApi[i]._id === id) {
                setName(fromApi[i].name);
            }
        }
      }
    }, [fromApi])
    
    return (
        <div>
            {name && <h2 className='urname'>Your name: {name}</h2>}
        </div>
    )
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related