Reputation: 1654
I red about getDerivedStateFromProps
but it seems that this not what I need. I am executing the code above and infinite loop occurs. How can I prevent that? Need to update quiz questions on every update. The code:
async componentDidUpdate() {
await this.questions();
}
questions = async () => {
const questions = await Promise.all(
this.props.navigation.getParam("quizzes").subQuiz.map(async (quiz) => {
const quizQuestions = await firebase
.firestore()
.collection("questions")
.where("quizId", "==", quiz.uid)
.get();
return quizQuestions.docs.map((quizQ) => {
return { uid: quizQ.id, ...quizQ.data() };
});
})
);
const quizzes = this.props.navigation.getParam("quizzes").subQuiz;
let final = [];
for (let i = 0; i < quizzes.length; i++) {
const quiz = quizzes[i];
const quizQuestions = questions[i];
final.push([
{
quiz: {
...quiz,
quizQuestions: {
...quizQuestions,
},
},
},
]);
}
this.setState({ quizzes: final }, () => {
console.log("TUKASME", this.state.quizzes[0].quiz);
});
};
Thankful for every advice!react-
Upvotes: 0
Views: 61
Reputation: 78848
You'll want to only do the update if props.navigation.getParams('quizzes')
is different from last time you updated. One way you can do this is by storing the quizzes
parameter in an instance variable:
componentDidUpdate() {
const currentParam = this.props.navigation.getParam("quizzes");
if (currentParam !== this.lastQuizzes) {
this.lastQuizzes = currentParam;
this.questions();
}
}
If you're feeling ambitious and want to convert to a functional components pattern with hooks, they've got a much easier technique to conditionally update using useEffect
:
import { useEffect, useState } from 'react';
function MyComponent({ navigation }) {
const [state, setState] = useState();
const quizzesParam = navigation.getParam('quizzes');
useEffect(() => {
updateQuizzes();
}, [quizzesParam]);
async function updateQuizzes() {
const questions = await Promise.all(
quizzesParam.subQuiz.map(async (quiz) => {
const quizQuestions = await firebase
.firestore()
.collection("questions")
.where("quizId", "==", quiz.uid)
.get();
return quizQuestions.docs.map((quizQ) => {
return { uid: quizQ.id, ...quizQ.data() };
});
})
);
const quizzes = quizzesParam.subQuiz;
let final = [];
for (let i = 0; i < quizzes.length; i++) {
const quiz = quizzes[i];
const quizQuestions = questions[i];
final.push([
{
quiz: {
...quiz,
quizQuestions: {
...quizQuestions,
},
},
},
]);
}
setState({ ...state, quizzes: final });
}
// Render...
}
With this pattern, the effect only fires on initial mount or if the values in the array change.
Upvotes: 2