I initialize the state to an empty object at first but then in my async function I fetch data from an API containing an object. In the same function I log the data to the console and setState to data, using it in another component as a prop and logging it there. It return one empty object and an object full of my data when I am expecting two objects full of data. Any help?
import Input from "./components/Input";
import "./App.css";
import { useEffect, useState } from "react";
async function fetchLoc(value) {
const res = await fetch(
`https://api.openweathermap.org/data/2.5/weather?
q=${value}&appid=${key}&units=imperial`
);
const data = await res.json();
console.log(data);
setState(data);
}
return (
<div className="App">
<img src={imgSrc} className="cover-img"></img>
<Input onFetch={fetchLoc} data={state}></Input>
</div>
);
}
export default App;
Here is the other component where I am calling the async function and logging the state.
import "./Input.css";
import { useState, useEffect } from "react";
const Input = (props) => {
const [val, setVal] = useState("");
const changeHandler = (e) => {
setVal(e.target.value);
};
const clickHandler = () => {
props.onFetch(val);
console.log(props.data.weather);
};
return (
<div>
<input
placeholder="🔎 Type in your city... "
onChange={changeHandler}
></input>
<button onClick={clickHandler}>Click me</button>
</div>
);
};
export default Input;
2
Answers
it seems that you’re using the setState method to update the state with the fetched data, but you haven’t declared the state variable or initialized it to an empty object. To fix this, you can add the useState hook to your App component to declare the state variable and initialize it as an empty object.
try the following:
Now I think your state variable is declared and initialized properly.
In your Input component, when you log props.data.weather, it may not display the fetched data correctly because it takes some time for the API call to complete and update the state so may not be immediately reflected in the props of the child component.
To address this issue, you can utilize the useEffect hook in your Input component to watch for changes in the props.data. When the props.data changes, you can log the updated props.data.weather value:
Now, when you click the "Click me" button, it will trigger the API call, update the state, and log the props.data.weather value when the state changes.
The fetch() call to the API should be placed inside either
You can fetch the data directly inside the child component. No need to pass a handler from parent to child in this case.
Here is an implementation: