I am new to React, and I'm currently learning about useState
and useEffect
. I have successfully fetched data from my local api using axios
. For development purposes, I'm intentionally changing the data directly from my database, to see if data changes would reflect in my React app. But, whenever I do so, my app breaks. I have included a screenshot of the error.
Here is my code:
function App() {
const[applicant, setApplicant] = useState("");
useEffect(() => {
axios.get("http://localhost:5000/application/1")
.then((res) => {
setApplicant(res.data);
console.log(res.data.personalInfo.firstName);
})
.catch((err) => console.log(err));
}, []);
return (
<div><h1>Welcome {applicant.personalInfo.firstName}</h1></div>
);
}
So here's the weird part (at least for me). On first load, everything works perfectly fine. But when I change first_name
field directly in my database, my app breaks. Here's the screenshot:
Obervation 1: if I change the array dependency of my useEffect
to always look at changes in applicant
state, the error will not occur. But as you might have already guessed, it causes an infinite loop request.
Observation 2: after my app breaks due to changes in database, if I temporarily remove that part in my JSX where I rendered the fetched data in my component: <h1>Welcome {applicant.personalInfo.firstName}</h1>
, refresh the page, then paste it back again, and refresh again, the error disappears, and the newly updated first_name
renders successfully.
Can someone tell me what's going on here, and mybe a better way of implementing this? Thanks a lot!
Edit: This is a screenshot of my json data:
So I found the problem. Basically, the type of my state is string, but in my setApplicant()
, I'm setting its value to the returned json object. So I just changed the default state type to be an empty object, like so:
const[applicant, setApplicant] = useState({});
Then, in my useEffect
hook:
setApplicant(res.data.personalInfo); //setting it to personalInfo object
Then, to access its attributes:
<h1>Welcome {applicant.firstName}</h1>