This is my code in codepan: https://codesandbox.io/s/relaxed-drake-4juxg?file=/src/Persons/persons.jsx
I don't have any idea why it is throwing an error that cannot read property data of undefined when sometimes it is reading it!
I have created a json file in my public folder:
[
{
"id": 0,
"name": "John",
"lastName": "Doe",
"address": "Main Street",
"gender": "male",
"country": "USA",
"city": "LA"
},
{
"id": 1,
"name": "Michael",
"lastName": "Zeburgee",
"address": "Second Street",
"gender": "male",
"country": "Germany",
"city": "Hamburg"
},
{
"id": 3,
"name": "Julia",
"lastName": "Hleb",
"address": "St.Patric",
"gender": "female",
"country": "Belarus",
"city": "Minsk"
},
{
"id": 4,
"name": "Petar",
"lastName": "Pan",
"address": "Some Street",
"gender": "male",
"country": "UK",
"city": "London"
}
]
I have an axios request:
import axios from "axios";
export default async function getPersonsInfo() {
const response = await axios.get("persons.json");
return response;
}
There is a Persons component:
import React, { useState } from "react";
import { useQuery } from "react-query";
import getPersonsInfo from "../api/personCalls";
export default function Persons() {
const [persons, setPersons] = useState([]);
const { data: personsData, status } = useQuery(
"personsData",
getPersonsInfo,
{
onSuccess: () => {
setPersons(personsData.data);
},
onError: (error) => {
console.log(error);
}
}
);
return (
<>
{status === "loading" ? (
<div>Loading ... </div>
) : (
<div>
{persons.map((person) => (
<div>
<p>{person.name}</p>
<p>{person.lastName}</p>
<p>{person.address}</p>
<p>{person.gender}</p>
<p>{person.country}</p>
<p>{person.city}</p>
</div>
))}
</div>
)}
</>
);
}
The problem is that it cannot read the data, but if I console.log(personsData) there is data.
onSuccess: () => {
setPersons(personsData.data);
},
You can see in the codepan. First when you open the file it is Loading... and fetching the data, but once you refresh the page it cannot!
useQueryalready manages the state. Just usedata: personDatadirectly.datais not an array before the query is complete, so you have to provide some kind of default state that takes this into account, like(data || []).map(/* ... */)