Home > database >  API call in useEffect returning undefined
API call in useEffect returning undefined

Time:03-02

I have a simple functional component, which includes a fetch to a JSON file stored locally.

I am trying to bring in the data from the JSON file, and whilst this should be a simple task, I have come across a problem.

My console log is showing two separate logs - one is an empty object, presumably from the useState definition and the second has the data from the fetch inside it.

Therefore, When I try to do anything with the data I'm fetching, undefined is being returned, So I can't use it. I feel like I'm missing something obvious, but I'm not entirely sure what is going on here. I have tried async/await without success.

What am I missing ?

const Landing = () => {
    const [api, updateApi] = useState({});

    const getData = () => {
      fetch('data.json')
      .then((response) => response.json())
      .then((data) => updateApi({api: {data}}))
    }
    useEffect(() => {
      getData();
    }, []);

    console.log(api)
  
    return (
        <p>Hey!</p>
    )
}

CodePudding user response:

All you need to do is to wrap the return within an if/else block, and return (for example a spinning circle) loading indicator. When it re-renders with the data from the api, it returns the desired representation of the data.

CodePudding user response:

Using async/await syntax you can put your fetch requests within the useEffect hook and set your state similar to how you are currently doing.

export default function Landing() {
  const [api, updateApi] = useState({});

  useEffect(() => {
    const getData = async () => {
      const response = await fetch("data.json");
      const data = await response.json();
      updateApi({ api: { data } });
    };
    getData();
  }, []);

  return <div>{JSON.stringify(api)}</div>;
}

If you initialise the state with useState({}) then the value won't be undefined. If however you want to check for that before doing something then an if/else statement as suggested in another answer is suitable or if it is within the component return then a common pattern is return <div>{api && JSON.stringify(api)}</div>;.

CodePudding user response:

Maybe you`re missing the fetch return:

const Landing = () => {
    const [api, updateApi] = useState({});

    const getData = () => {
      fetch('data.json')
      /* return the json */
      .then((response) => return response.json())
      .then((data) => updateApi({api: {data}}))
    }
    useEffect(() => {
      getData();
    }, []);

    console.log(api)
  
    return (
        <p>Hey!</p>
    )
}
  • Related