0

Hellooo,

This is my first time using React. I want to fetch some data in json format and list it out in my page. The code below is not working.

import React, { useState, useEffect } from "react";
import axios from "axios";

function DataFetching() {
  const [users, setUsers] = useState({ hits: [] });
  //const [query, setQuery] = useState("redux");

  useEffect(async () => {
    const fetchData = async () => {
      const result = await axios("url");
      setUsers(result.data);
    };
  }, []);

  return (
    <div>
      <p>Hellooooo</p>
      <ul>
        {users.hits.map((user) => (
          <li key={user.id}>{user.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default DataFetching;
8
  • You would need to call fetchData() within your useEffect handler. That or just remove the extra function and call axios directly Commented May 19, 2021 at 5:10
  • When you say it is not working what do you mean? Is the response data from axios not available or you are getting some kind of error Commented May 19, 2021 at 5:19
  • @ShubhamKhatri OP isn't calling fetchData anywhere so the request is never made Commented May 19, 2021 at 5:21
  • When I used the above useEffect function I am getting the fikkiwing error. Uncaught TypeError: users.hits is undefined Commented May 19, 2021 at 5:22
  • 1
    The response from https://jsonplaceholder.typicode.com/users is an array, not an object and certainly not one with a hits property. Commented May 19, 2021 at 5:36

1 Answer 1

6

Issue

  1. useEffect hook callbacks are 100% synchronous, they can't be asynchronous (i.e. declared async) at all. This also implicitly returns a Promise and messes with the effect cleanup functionality.
  2. Your code never calls the fetchData function, so nothing is really updated.
  3. You stomp your state shape and place the result array at the root state level instead of in an object under the hits key.

Solution

  1. Remove the async keyword from the effect callback.
  2. Invoke fetchData in the effect callback body.
  3. Update state correctly.

Code:

useEffect(() => {
  const fetchData = async () => {
    try {
      const result = await axios("url");
      setUsers({ hits: result.data });
    } catch(error) {
      // handle any GET request or response handling errors
    }
  };
  fetchData();
}, []);

Edit priceless-dew-qbhtu

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

Excellent point about the useEffect return value. I totally forgot about cleanup.
Point (1) is a little weirdly put – of course the effect function can do asynchronous things, it just can't be async, since it'd make it implicitly return a Promise.
Hi thank you but I am not sure why I am getting an error stating ``` Uncaught TypeError: users.hits is undefined ```.
I corrected it using. ``` const [users, setUsers] = useState([]); ``` and ``` users && users.map((user) => <li key={user.id}>{user.name}</li>)} ```
@AKX Not really sure what point you are trying to make, I didn't say the useEffect callback couldn't do asynchronous things, but that the callback itself can't be asynchronous. I did update to expressly call out the use of async keyword in the issues even though I felt it was already clear enough in context with the solution. Thanks for the input.
|

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.