DEV Community

kheersagar parja
kheersagar parja

Posted on • Edited on

Update State After API Response React!!!

Have you ever wounder why immediately after updating the state if it is logged, value is undefined??

  const fetchAPI = async () => {
    const res = await axios.get("https://catfact.ninja/fact");
    setData((previousData) => ({ ...previousData, ...res.data }));
    console.log("response from API: \n" + res.data.fact);
    console.log("State Data: \n" + data.fact);
  };
Enter fullscreen mode Exit fullscreen mode

Console


response from API: 
The smallest wildcat today is the Black-footed cat. The females are less than 20 inches (50 cm) long and can weigh as little as 2.5 lbs (1.2 kg). 

State Data: 
undefined 
Enter fullscreen mode Exit fullscreen mode

Whole Code

import axios from "axios";
import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [data, setData] = useState({});
  const [count, setCount] = useState(0);
  const fetchAPI = async () => {
    const res = await axios.get("https://catfact.ninja/fact");
    setData((previousData) => ({ ...previousData, ...res.data }));
    console.log("response from API: \n" + res.data.fact);
    console.log("State Data: \n" + data.fact);
    if (data.fact) {
      setCount(data.fact.length);
    }
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <div>
        <h1>Fact:</h1>
        <h2>{data.fact}</h2>
        <h2>charact count : {count}</h2>
      </div>
      <button onClick={fetchAPI}>fetch API</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Refer video below:

Image description

On clicking Fetch Api Button
State is not updated immediately and if following code is dependent, then it does work.

Its because how react updates the state and re-renders
React update state in batches, means It will register the update state function in a queue and after running all the code it executes the state queue and re-renders.
That's why if we log just after setData() function we get undefined but if we click on fetch api button again we get previous value.

For more information how react updates state [click here]

How to fix this and execute code as soon as state is updated?

Fix: UseEffect
It takes a callback function and a dependency array, this can be used to fix the problem of running dependent code after state is updated

  useEffect(() => {
    console.log("updated DATA \n" + data.fact);
    setCount(0); // to eleminate race condition
    if (data.fact) {
      setCount(data.fact.length);
    }
  }, [data]);
Enter fullscreen mode Exit fullscreen mode

Whole Code

import axios from "axios";
import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [data, setData] = useState({});
  const [count, setCount] = useState(0);
  const fetchAPI = async () => {
    const res = await axios.get("https://catfact.ninja/fact");
    setData((previousData) => ({ ...previousData, ...res.data }));
    console.log("response from API: \n" + res.data.fact);
  };
  useEffect(() => {
    console.log("updated DATA \n" + data.fact);
    if (data.fact) {
      setCount(data.fact.length);
    }
  }, [data]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <div>
        <h1>Fact:</h1>
        <h2>{data.fact}</h2>
        <h2>charact count : {count}</h2>
      </div>
      <button onClick={fetchAPI}>fetch API</button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Image description

Top comments (0)