Массив React State, измененный после развертывания - PullRequest
0 голосов
/ 05 апреля 2020

Приложение «Мой рулон костей» бросает кости и регистрирует предыдущие броски.

Приложение можно увидеть на страницах github: https://mtrussell.github.io/dice-roll-app/

Чтобы просмотреть все код приложения, вот репо: https://github.com/mtrussell/dice-roll-app

Компонент RollDice добавляет текущий рулон в массив рулонов. Компонент PrevRolls обращает массив и сопоставляет его с элементами jsx.

Проблема заключается в том, что при развертывании его на страницах github он ведет себя не так, как на моем локальном компьютере. Кажется, что он через секунду меняет массив, переворачивая его обратно.

Я думал, что это как-то связано с таймаутом кнопки, но я полностью это убрал, и шаткое поведение сохранялось.

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

Компонент RollDice -

import React, { Component } from 'react';
import Die from './Die';
import PrevRolls from './PrevRolls';
import './RollDice.css';

class RollDice extends Component {
  static defaultProps = {
    sides: ['one', 'two', 'three', 'four', 'five', 'six']
  }

  constructor(props) {
    super(props);
    this.state = {
      die1: 'one',
      die2: 'two',
      rolling: false,
      rolls: []
    }
    this.handleClick = this.handleClick.bind(this);
  }

  randomDice() {
    const newDie1 = this.props.sides[
      Math.floor(Math.random() * this.props.sides.length)
    ];
    const newDie2 = this.props.sides[
      Math.floor(Math.random() * this.props.sides.length)
    ];
    return [newDie1, newDie2];
  }

  roll(dice) {
    this.setState(prevState => {
      return {
        die1: dice[0], 
        die2: dice[1], 
        rolling: true,
        rolls: [...prevState.rolls, {first: dice[0], second: dice[1]}]
      }     
    });
  }

  handleClick() {
    const dice = this.randomDice();
    this.roll(dice);
    setTimeout(() => {
      this.setState({
        rolling: false,
      });
    }, 1000);
  }


  render() {
    let rollButton = this.state.rolling ? 'Rolling...' : 'Roll Dice!';

    return(
      <div className='RollDice'>
        <div className='RollDice-dice'>
          <Die face={this.state.die1} rolling={this.state.rolling} />
          <Die face={this.state.die2} rolling={this.state.rolling} />
        </div>
        <button onClick={this.handleClick} disabled={this.state.rolling}>{rollButton}</button>
        <PrevRolls rolls={this.state.rolls} />
      </div>
    );
  }
}

export default RollDice;

Компонент PrevRolls -

import React, { Component } from 'react';
import './PrevRolls.css'

class PrevRolls extends Component {
  constructor() {
    super();
    this.displayRolls = this.displayRolls.bind(this);
  }

  reverseRolls() {
    return this.props.rolls.reverse();
  }

  displayRolls() {
    return this.reverseRolls().map((roll, index) => (
      <p>
        Roll {this.props.rolls.length - index} <i className={`fas fa-dice-${roll.first}`} ></i> <i className={`fas fa-dice-${roll.second}`} ></i>
      </p>
    ));
  }

  render() {
    return(
      <div className='PrevRolls'>
        <div className='PrevRolls-list'>
          {this.displayRolls()}
        </div>
      </div>
    );
  }
}

export default PrevRolls;

1 Ответ

0 голосов
/ 06 апреля 2020

Благодаря xadm я понял это. reverse () изменял массив родительского компонента.

Я изменил способ установки состояния в функции roll () в компоненте RollDice.

В компоненте PrevRolls я удалил reverseRolls () и вызов ее функции в функции displayRolls ().

Компонент RollDice -

roll(dice) {
    this.setState(prevState => {
      return {
        die1: dice[0], 
        die2: dice[1], 
        rolling: true,
        rolls: [{first: dice[0], second: dice[1]}, ...prevState.rolls]
      }     
    });
  }

Компонент PrevRolls -

displayRolls() {
    return this.props.rolls.map((roll, index) => (
      <p>
        Roll {this.props.rolls.length - index} <i className={`fas fa-dice-${roll.first}`} ></i> <i className={`fas fa-dice-${roll.second}`} ></i>
      </p>
    ));
  }
...