Использование React, реализация викторины - анимация работает немного «странно» - PullRequest
0 голосов
/ 14 февраля 2020

Я создал приложение для викторины, используя React: https://codesandbox.io/s/eloquent-kare-gczfw

Было бы здорово получить отзывы, особенно анимацию, которая происходит при нажатии кнопки «Далее». Я понял, что анимация происходит вначале, потом не происходит, потом повторяется. Интересно, что мне не хватает, чтобы анимация происходила при каждом нажатии кнопки «Далее».

Я создал поле состояния «Анимация» в компоненте Викторина, чтобы оно переходило от ложного к истинному, и наоборот versa.

class Quiz extends React.Component {
  state = {
    currentQuiz: 0,
    numOfQuestions: 0,
    score: 0,
    resultSummary: false,
    animation: false
  };

  handleNextQuestion = answer => {
    const { currentQuiz, numOfQuestions, score } = this.state;

    if (answer) {
      this.setState({
        score: score + 1,
        numOfQuestions: numOfQuestions + 1
      });
    } else {
      this.setState({
        numOfQuestions: numOfQuestions + 1
      });
    }

    if (numOfQuestions === quizzes[currentQuiz].questions.length - 1) {
      this.setState({
        numOfQuestions,
        resultSummary: true
      });
    }

    if (!this.state.animation) {
      this.setState({ animation: "multiple-choices" });
    } else {
      this.setState({ animation: false });
    }
  };

  handleNextQuiz = () => {
    const { currentQuiz } = this.state;

    if (currentQuiz + 1 === quizzes.length) {
      this.setState({
        resultSummary: false,
        numOfQuestions: 0,
        score: 0,
        currentQuiz: 0
      });
    } else {
      this.setState({
        resultSummary: false,
        numOfQuestions: 0,
        score: 0,
        currentQuiz: currentQuiz + 1
      });
    }
  };

  render() {
    const {
      currentQuiz,
      numOfQuestions,
      score,
      resultSummary,
      animation
    } = this.state;

    const { title, questions } = quizzes[currentQuiz];
    const currentQuestion = questions[numOfQuestions];

    const shuffledAnswerChoices = shuffle([
      ...currentQuestion.incorrectAnswers,
      currentQuestion.correctAnswer
    ]);

    return (
      <div className="container">
        <h1>{title}</h1>
        {resultSummary ? (
          <Result
            score={score}
            numOfQuestions={numOfQuestions}
            nextQuizHandler={this.handleNextQuiz}
          />
        ) : (
          <Question
            currentQuestion={currentQuestion}
            shuffledAnswerChoices={shuffledAnswerChoices}
            nextQuestionHandler={this.handleNextQuestion}
            animation={animation}
          />
        )}
      </div>
    );
  }
}

export default Quiz;

Также интересно, есть ли 1) лучший способ управления состоянием в этом приложении и 2) советы по медиазапросам для мобильных устройств (я вроде новичка в адаптивном дизайне).

1 Ответ

1 голос
/ 14 февраля 2020

В реакции. js setState является асинхронным и пакетирует / откладывает обновления состояния, в результате чего компонент не обновляется мгновенно. Это может привести к тому, что изменения вашего состояния станут несинхронными c, и в вашем случае функция handleNextQuestion потенциально имеет 3 setState вызовов, которые действительно полагаются друг на друга, чтобы визуализировать компонент так, как вам нравится.

Я бы порекомендовал использовать функцию обратного вызова с вашим setState, чтобы функция обратного вызова происходила после применения setState.

handleNextQuestion = answer => {
...
this.setState({
  score: score + 1,
  numOfQuestions: numOfQuestions + 1
}, this.applyAnimation);

}
....

applyAnimation() {
  return !this.state.animation ? this.setState({ animation: "multiple-choices" }) : this.setState({ animation: false });
}

Еще один способ улучшить ваш код - объединить изменения состояния и применить их вместе, а не 3 отдельных вызова в одной функции. Существуют библиотеки анимации, такие как response-transition-group , которые могут помочь с изменениями состояния анимации.

Для получения подсказок по медиа-запросам сосредоточьтесь на создании отзывчивого на мобильном * css, поэтому вы можете переопределить стилирование, например, для маленьких, средних и больших экранов. Это уменьшит количество кода, необходимого для создания адаптивных компонентов. Также максимально используйте flexbox .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...