Home > Enterprise >  useState returns an empty array while console.log does not?
useState returns an empty array while console.log does not?

Time:12-11

I have fairly limited experience with React Native. I've set up similar API-calls before without trouble, but for some reason can't get this one to work.

I have the following code which includes state variables and the API fetch function.

export default function App() {
  const [users, setUsers] = useState([]);
  const [villages, setVillages] = useState([]);

  async function getUsers() {
    const response = await fetch("https://localhost:7108/PlayersAPI/1");
    const users = await response.json();
    setUsers(users[0]);
    console.log("Before calling setVillages:", users[0].villages[0]); // log the value before calling setVillages
    setVillages(users[0].villages[0].villageId);
    console.log(villages);
    console.log("After calling setVillages:", users[0].villages[0]); // log the value after calling setVillages
  }

The function runs from a useEffect:

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

The response I get from the API looks like this:

[
  {
    "playerId": 1,
    "username": "Sebastian",
    "villages": [
      {
        "villageId": 1,
        "name": "Söderstadion",
        "resourceFields": [
          {
            "resourceFieldId": 1,
            "level": 2,
            "typeOfResource": 0,
            "villageId": 1,
            "village": null
          },
          {
            "resourceFieldId": 2,
            "level": 1,
            "typeOfResource": 1,
            "villageId": 1,
            "village": null
          },
          {
            "resourceFieldId": 3,
            "level": 2,
            "typeOfResource": 2,
            "villageId": 1,
            "village": null
          },
          {
            "resourceFieldId": 4,
            "level": 1,
            "typeOfResource": 3,
            "villageId": 1,
            "village": null
          }
        ],
        "player": null,
        "playerId": 1,
        "villageData": {
          "villageDataId": 1,
          "wood": 7900,
          "iron": 7900,
          "clay": 7900,
          "maxStorage": 8000,
          "crop": 20,
          "maxCrop": 8000,
          "woodProduction": 100,
          "ironProduction": 150,
          "clayProduction": 100,
          "cropProduction": 100,
          "resourcesLastUpdated": "2022-12-08T21:52:35.8305912",
          "villageId": 1,
          "village": null
        },
        "armies": null,
        "tileId": 11,
        "tile": {
          "tileId": 11,
          "worldMapId": 1,
          "worldMap": null,
          "coordinate": null,
          "village": null
        }
      },
      {
        "villageId": 2,
        "name": "Kennedy",
        "resourceFields": [
          {
            "resourceFieldId": 5,
            "level": 1,
            "typeOfResource": 0,
            "villageId": 2,
            "village": null
          },
          {
            "resourceFieldId": 6,
            "level": 2,
            "typeOfResource": 1,
            "villageId": 2,
            "village": null
          },
          {
            "resourceFieldId": 7,
            "level": 2,
            "typeOfResource": 2,
            "villageId": 2,
            "village": null
          },
          {
            "resourceFieldId": 8,
            "level": 1,
            "typeOfResource": 3,
            "villageId": 2,
            "village": null
          }
        ],
        "player": null,
        "playerId": 1,
        "villageData": {
          "villageDataId": 2,
          "wood": 8000,
          "iron": 8000,
          "clay": 8000,
          "maxStorage": 8000,
          "crop": 120,
          "maxCrop": 8000,
          "woodProduction": 150,
          "ironProduction": 150,
          "clayProduction": 100,
          "cropProduction": 100,
          "resourcesLastUpdated": "2022-12-08T21:52:35.8319058",
          "villageId": 2,
          "village": null
        },
        "armies": null,
        "tileId": 12,
        "tile": {
          "tileId": 12,
          "worldMapId": 1,
          "worldMap": null,
          "coordinate": null,
          "village": null
        }
      },
      {
        "villageId": 3,
        "name": "Ludwigsson",
        "resourceFields": [
          {
            "resourceFieldId": 9,
            "level": 1,
            "typeOfResource": 0,
            "villageId": 3,
            "village": null
          },
          {
            "resourceFieldId": 10,
            "level": 2,
            "typeOfResource": 1,
            "villageId": 3,
            "village": null
          },
          {
            "resourceFieldId": 11,
            "level": 1,
            "typeOfResource": 2,
            "villageId": 3,
            "village": null
          },
          {
            "resourceFieldId": 12,
            "level": 2,
            "typeOfResource": 3,
            "villageId": 3,
            "village": null
          }
        ],
        "player": null,
        "playerId": 1,
        "villageData": {
          "villageDataId": 3,
          "wood": 8000,
          "iron": 8000,
          "clay": 8000,
          "maxStorage": 8000,
          "crop": 120,
          "maxCrop": 8000,
          "woodProduction": 150,
          "ironProduction": 100,
          "clayProduction": 100,
          "cropProduction": 150,
          "resourcesLastUpdated": "2022-12-08T21:52:35.8319149",
          "villageId": 3,
          "village": null
        },
        "armies": null,
        "tileId": 13,
        "tile": {
          "tileId": 13,
          "worldMapId": 1,
          "worldMap": null,
          "coordinate": null,
          "village": null
        }
      }
    ],
    "playerData": {
      "playerDataId": 1,
      "wood": 100,
      "iron": 750,
      "clay": 350,
      "maxStorage": 800,
      "crop": 120,
      "maxCrop": 800,
      "woodProduction": 100,
      "ironProduction": 100,
      "clayProduction": 100,
      "cropProduction": 0,
      "resourcesLastUpdated": "2022-12-04T20:00:09.3110368",
      "playerId": 1,
      "player": null
    }
  }
]

The users state works as expected, it fetches everything that has to do with the first player (in this case there is only one though). I can then console.log(users[0].villages[0]) and get the exact output I'm interested in, an object looking like this:

{
    "villageId": 1,
    "name": "Söderstadion",
    "resourceFields": [
        {
            "resourceFieldId": 1,
            "level": 2,
            "typeOfResource": 0,
            "villageId": 1,
            "village": null
        },
        {
            "resourceFieldId": 2,
            "level": 1,
            "typeOfResource": 1,
            "villageId": 1,
            "village": null
        },
        {
            "resourceFieldId": 3,
            "level": 2,
            "typeOfResource": 2,
            "villageId": 1,
            "village": null
        },
        {
            "resourceFieldId": 4,
            "level": 1,
            "typeOfResource": 3,
            "villageId": 1,
            "village": null
        }
    ],
    "player": null,
    "playerId": 1,
    "villageData": {
        "villageDataId": 1,
        "wood": 7900,
        "iron": 7900,
        "clay": 7900,
        "maxStorage": 8000,
        "crop": 20,
        "maxCrop": 8000,
        "woodProduction": 100,
        "ironProduction": 150,
        "clayProduction": 100,
        "cropProduction": 100,
        "resourcesLastUpdated": "2022-12-08T21:52:35.8305912",
        "villageId": 1,
        "village": null
    },
    "armies": null,
    "tileId": 11,
    "tile": {
        "tileId": 11,
        "worldMapId": 1,
        "worldMap": null,
        "coordinate": null,
        "village": null
    }
}

But for the life of me I cannot get setVillages(users[0].villages[0].villageId); to work. All it returns is an empty array. I've set up a console.log before and after setVillages is used, and both return the object. But when I console.log(villages) it returns an empty array [].

What is it that I'm missing here?

CodePudding user response:

use it inside a useEffect to detect changes since usestate is asynchronous.

useEffect(() => {
  console.log(villages)
}, [villages])
  • Related