I used axios in useEffect of my wrapper component and I sent the data as props to the other component "singleQuestionnaire", in singleQuestionnaire component, I destructured the data, in the first try, it works fine, but after reloading the page it doesn't work with an error : can not read property "map" of undefined
import React, { useEffect, useState } from "react";
import SingleQuestionnaire from "./SingleQuestionnaire";
import { fetchQuestions } from "../../../api/index";
const Questionnaires = ({ match }) => {
const [questions, setQuestions] = useState([]);
const pid = match.params.id;
const getQuestionnaire = async (pid) => {
try {
const { data } = await fetchQuestions(pid);
console.log(data.data, "action in component");
setQuestions(data.data);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
getQuestionnaire(pid);
}, []);
console.log("all questions", questions);
return (
<div>
<SingleQuestionnaire questions={questions} setQuestions={setQuestions} />
</div>
);
};
export default Questionnaires;
and this is my singleQuestionnaire component:
import React, { useEffect, useState } from "react";
const SingleQuestionnaire = ({ questions, setQuestions }) => {
const [questionnaire, setQuestionnaire] = useState([]);
console.log(questions);
const { data } = questions;
console.log("data", data.farmInformationQuestionnaireData);
return <div>simple component</div>;
};
export default SingleQuestionnaire;
For the first time, in console I can see the data "data.data.farmInformationQuestionnaireData". It's an array but for the second time it's undefind.
CodePudding user response:
because questions in SingleQuestionnaire
is an empty array before we fetch
which causes an error here
const { data } = questions;
you can add a loading text because initially questions
will be an empty array then it will be your res.data
(assuming it's an object)
const SingleQuestionnaire = ({ questions, setQuestions }) => {
const [questionnaire, setQuestionnaire] = useState([]);
console.log(questions);
if(questions.length === 0 ) return <h1> Loading</h1>
const { data } = questions;
console.log("data", data.farmInformationQuestionnaireData);
return <div>simple component</div>;
};
CodePudding user response:
it is happening because of the async API call. When you make an async call, the thread does not wait, it moves on and it starts executing other things. Now your async call might be complete but your callback will not be executed until the stack is empty, that's just how javaScript works. I recommend you use some kind of loader gif or text
{questions ? <SingleQuestionnaire questions={questions} setQuestions={setQuestions} /> : <p>Loading...</p>}