Search code examples
reactjsapiaxiosuse-effectuse-state

React App breaks after changing data directly in mysql database


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:

enter image description here

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:

enter image description here


Solution

  • 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>