2

I'm trying to fetch data from an API and load that data onto a website using React. Currently, I am calling the fetch function using async and await. I printed out the results of the fetch call and all seems to be working properly. What I don't understand is why my studentsJSON array is still empty even though there is an array in data.students.

  const [studentsJSON, setStudentsJSON] = useState([])
  const [students, setStudents] = useState([])

  useEffect(() => {
    async function fetchData() {
      const response = await fetch(URL)
      const data = await response.json()
      console.log(`data.students: ${data.students}`)
      setStudentsJSON(data.students)
      console.log(`studentsJSON: ${studentsJSON}`)
      for (let student of studentsJSON) {
        setStudents(students => [...students, new Student(student)])
      }
      console.log(`students: ${students}`)
    }

    fetchData()
  }, [])

Output:

data.students: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
App.js:36 studentsJSON: 
App.js:40 students: 
2
  • State is constant within a particular render of a component; for component to see the updated state, it has to re-render. As a result, logging the state right after calling the state updater function will log the old state. You can use useEffect hook to log the updated state: useEffect(() => { console.log(studentsJSON); }, [studentsJSON]); Commented Jun 21, 2021 at 6:05
  • Please make another function outside of useEffect pass your state into that function and inside the function place yours for a loop. or make a callback of setStudentsJSON Commented Jun 21, 2021 at 6:18

3 Answers 3

0
  1. await response.json() already turns your JSON into a JS data structure so the studentsJSON and setStudentsJSON state really makes no sense.

  2. You might want to reconsider how you update your state. map over the data to create a new array, create a new state array, and then update your student state in one move.

    const newStudents = data.students.map(student => new Student(student));
    const newState = [...students, newStudents].flat();
    setStudents(newState);
    
Sign up to request clarification or add additional context in comments.

Comments

0

You can't see your studentsJSON because setState (setStudentsJSON) is an asynchronous operation, and by the time it runs the command console.log the state value studentsJSON is still an empty array.

Instead of logging the result immediately after setState, you can put it inside another useEffect hook:

useEffect(() => {
  console.log(studentsJSON);
}, [studentsJSON]);

Comments

0

Try using promises. This solves the problem of setting state empty.

 const response = await fetch(URL).then((res)=>setStudentsJSON( res.json()))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.