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])