Josh Zepeda
Josh Zepeda

Reputation: 63

Why is my React Use-Effect Hook Not Working?

I am re-posting a question I asked a week ago where I left out the steps I took to solve the issue. I am working on a simple MERN app off a tutorial and the use-effect function is not rendering the content onto the page. Here is the code:

App.js File

import './App.css';
import { useState, useEffect } from 'react';
import Axios from 'axios';

function App() {
  const [listOfUsers, setListOfUsers] = useState([]);

  useEffect(() => {
    Axios.get("http://localhost:3001/getUsersFakeDataGen").then((response) => {
      setListOfUsers(response.data)
    })
  }, [])

  return (
    <div className="App">
      <div className="usersDisplay">
        {listOfUsers.map((user) => {
          return (
            <div>
              <h1>Name: {user.name}</h1>
              <h1>Age: {user.age}</h1>
              <h1>Username: {user.username}</h1>
            </div>
          )
        })}
     </div>
    </div>
  )
};

export default App;

I tested the functionality by commenting out the "useEffect()" function and putting in an object in the "useState([])" element of "function App()". That object did correctly render on the page, but when I deleted that object and un-commented useEffect(), the page was blank again.

I confirmed that my APIs are working because my API client (Thunder Client) is showing that the GET and POST requests are reading and writing to the database (MongoDB). Also, the server is working properly (confirmed by a console log).

Any suggestions would be appreciated. If more information is needed, please let me know. Thank you.

Upvotes: 1

Views: 2923

Answers (2)

besjon_c
besjon_c

Reputation: 172

if your problem is not resolved, yet I suggest the following:

  import axios from 'axios'
  ... 
  const [listOfUsers, setListOfUsers] = useState([]);

  const fetchData = async () => {
     const result = await axios.get("http://localhost:3001/getUsersFakeDataGen").then((response) => {
     setListOfUsers(response.data)
     return response.data;
  });

  useEffect(() => {
    fetchData();
  }, [])

Note [] in the useEffect, it means it will render only once when the page loads. Also I used async and await to wait for data to be retrieved before processing (maybe that's why you get empty elements). You can also setState outside of useEffect.

Upvotes: 1

Justin Meskan
Justin Meskan

Reputation: 683

import './App.css';
import { useState, useEffect } from 'react';
import Axios from 'axios';

function App() {
const [listOfUsers, setListOfUsers] = useState([]);

  useEffect(() => {
    Axios.get("http://localhost:3001/getUsers").then((response) => {
      setListOfUsers(response.data)
    })
  }, [listOfUsers]); // THIS IS WHERE YOU ADD YOUR useEffect DEPENDENCIES

  return (
    <div className="App">
      <div className="usersDisplay">
       {listOfUsers.map((user) => {
         return (
           <div>
             <h1>Name: {user.name}</h1>
             <h1>Age: {user.age}</h1>
             <h1>Username: {user.username}</h1>
            </div>
         )
        })}
    </div>
    </div>
 )

};

export default App;

OK look so the issue is if you only provided an empty array as your second argument. Your useEffect will only run one time, when you add stateful values to the array the useEffect will render every time that piece of state changes. If you omit the second argument the useeffect will run over and over again.

Also here-- Remember that you array starts empty, You need a check it's existence

{listOfUsers?.map.map((item))=>{}}

or

{listOfUsers.length && listOfUsers.map((item))=>{}}

.

    {listOfUsers.map((user) => {
      return (
        <div>
          <h1>Name: {user.name}</h1>
          <h1>Age: {user.age}</h1>
          <h1>Username: {user.username}</h1>
        </div>
      )
    })}

Upvotes: 0

Related Questions