在componentDidUpdate中更新状态会导致无限循环

时间:2020-04-16 22:33:13

标签: react-native

我为getDerivedStateFromProps着迷,但这似乎不是我所需要的。我正在执行上面的代码,并发生无限循环。我该如何预防?每次更新都需要更新测验问题。代码:

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);
    });
  };

感谢您的每一个建议!反应-

1 个答案:

答案 0 :(得分:2)

仅当props.navigation.getParams('quizzes')与上次更新不同时才进行更新。一种实现方法是将quizzes参数存储在实例变量中:

componentDidUpdate() {
  const currentParam = this.props.navigation.getParam("quizzes");
  if (currentParam !== this.lastQuizzes) {
    this.lastQuizzes = currentParam;
    this.questions();
  }
}

如果您有雄心勃勃并想使用钩子转换为功能组件模式,则可以使用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...
}

使用这种模式,效果只会在初始安装或数组中的值更改时触发。