React - синхронизированное действие не загружает определенный компонент - PullRequest
0 голосов
/ 25 декабря 2018

Что я хочу: когда таймер достигает 0 секунд, приложение монтирует один компонент и скрывает другие.Что происходит: ничего.

Я работаю над одностраничным приложением React.У меня проблема с поведением таймера, когда он достигает 0. Я хочу, чтобы он скрыл компоненты «Вопросы» и «Таймер» и показал только компонент «Результаты».Прямо сейчас логика в timerZero, но я попытался поместить ее в startTimer и / или clickStart, но ни одна из этих комбинаций не сработала.

Я также заметил, что если вы выберете ответы после того, как таймер достигнет 0, будет продолжено ведение журнала консоли "Время истекло!"на каждый выбор.Нажатие кнопки «Отправить» через 0 секунд все равно приведет вас к результатамDiv с правильными значениями, но не скроет таймер в соответствии с инструкциями.

Репо: https://github.com/irene-rojas/pixar-react

Приложение

import React, { Component } from 'react';
import './App.css';
import Timer from "./Timer";
import Questions from "./Questions/Questions.js";
import Results from "../src/Results";

class App extends Component {

state = {
    totalTrue: 0,
    totalFalse: 0,
    showTimer: true,
    showQuestions: false,
    showResults: false,
}

clickStart = (event) => {
    event.preventDefault();
    console.log("start button clicked");
    this.setState(
        {showQuestions: true}
    )
}

// submit button
handleFormSubmit = (event) => {
    event.preventDefault();
    console.log("submit button clicked");
    this.setState(
        {showResults: true,
        showQuestions: false,
        showTimer: false}
        // timer still appears in resultsDiv
    )
};

timerZero = () => {
    if (this.state.timer === 0) {
    this.setState(
        {showResults: true,
        showQuestions: false,
        showTimer: false}
    )
    }
    // nothing happens >:(
};

callbackHandlerFunction = ( selectedOption ) => {
    const answerValue = selectedOption.value;
    if (answerValue === true) {
        this.setState({totalTrue: this.state.totalTrue + 1}, () => {
            console.log(`New TotalTrue: ${this.state.totalTrue}`);
        });
    };
    if (answerValue === false) {
        this.setState({totalFalse: this.state.totalFalse + 1}, () => {
            console.log(`New TotalFalse: ${this.state.totalFalse}`);
        });
    };
  } 

  render() {
    return (

  <div className="parallax">

    <div className="App">

        <div className="wrapper">

        <div className="headerDiv">
            <h1>Pixar Trivia!</h1>
        </div>

        <div className="timerDiv">
            <Timer 
            handleTimerClick={this.clickStart}
            timeOut={this.timerZero}
            />   
        </div>

        {this.state.showQuestions &&
        <div className="questionSection">
            <Questions 
                handleClickInParent={this.callbackHandlerFunction}
            />

            <div>
                <button onClick={this.handleFormSubmit}>Submit</button>
            </div>
        </div>
        }

        {this.state.showResults && 
        <div className="resultsDiv">
            <Results 
                totalTrue={this.state.totalTrue}
                totalFalse={this.state.totalFalse}
            />
        </div>
        }

        </div>

    </div>

  </div>
    );
  }
}

export default App;

Таймер

import React, { Component } from 'react';

class Timer extends Component {

  state = {
    timer: 10
  };

  startTimer = (event) => {
    this.timer = setInterval(() => this.setState({
      timer: this.state.timer - 1}), 1000); 
    // onClick, load Questions
    this.props.handleTimerClick(event);
   };

  stopTimer = () => {
    clearInterval(this.timer);
    console.log("Time's up!");
    this.props.timeOut();
  };

  render() {
    return (
      <div className="Timer">
        <div>{this.state.timer} seconds</div>
        <button onClick={this.startTimer}>Start!</button>
        {this.state.timer === 0 && this.stopTimer()}
      </div>
    );
  }
}

export default Timer;

1 Ответ

0 голосов
/ 25 декабря 2018

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

App.js

// ...
/* 
    you were trying to read this.state.timer
    which is not decalred in this component
*/
timerZero = () => this.setState(
        {showResults: true,
        showQuestions: false,
        showTimer: false}
    )

// ...

render() {

{/* ... */}
{this.state.showTimer && (
    <div className="timerDiv">
        <Timer 
        handleTimerClick={this.clickStart}
        timeOut={this.timerZero}
        />  
    </div>
{/* ... */
)} 

Timer.js

// ...

  /* 
    I added `shouldComponentUpdate` lifecycle
    with this, we stop the `Timer` component for rendering
    and call `stopTimer` (instead of doing it inside the render method)
  */
  shouldComponentUpdate() {
    console.log(this.state.timer);
    if (this.state.timer <= 0) {
      this.stopTimer();
      return false;
    }
    return true;
  };
  /* 
    Also added the a componentWillUnmount method for good practice
    here if the component is unmounted the timer won't be running forever.
  */
  componentWillUnmount() {
    clearInterval(this.timer);
  };

  render() {
    return (
      <div className="Timer">
        <div>{this.state.timer} seconds</div>
        <button onClick={this.startTimer}>Start!</button>
        {/* delete the call to `this.stopTimer` */}
      </div>
    );
  }

Кроме того, я рекомендую игнорировать папку node_modules в файле .gitignore, чтобы сделать ваши проекты более простыми.все зависимости вашего проекта перечислены в yarn.lock или package-lock.json, поэтому, когда я загружаю репозиторий, я получаю загрузить те же зависимости, что и вы.

ура !!!

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