Реагируйте и индикатор выполнения. Как я могу добавить индикатор выполнения, который будет работать с моим вводом и моими данными - PullRequest
0 голосов
/ 26 февраля 2020

Мне нужно реализовать индикатор прогресса в моем приложении. Я создал угадайку покемонов. Я хочу добавить индикатор прогресса к нему. Теперь у меня есть х / 151 правильных ответов. Как я могу добавить индикатор выполнения?

Я нашел это: https://react-bootstrap.github.io/components/progress/

Но я не знаю, как его использовать, так что если кто-то может помочь.

Это моя GuessingGame. js

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


class GuessingGame extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            id: '',
            sprite: '',
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentDidMount() {
        const { url } = this.props
        const id = url.split('/')[6] //get the id from the end of each pokemon url so that we can generate the sprite url
        const sprite = `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${id}.png`;

        this.setState({
            id,
            sprite
        })
    }

    handleChange(event) {
        this.setState({ value: event.target.value });
    }

    handleSubmit(event) {
        event.preventDefault();
        this.guessPokemon();
    }

    guessPokemon() {
        if (this.props.name === this.state.value) {
            alert('You guessed right!')
            this.props.fetchData(true); 
        }
        else {
            alert('You guessed wrong!')
            this.props.fetchData(false);
        }
    }

    render() {
        const guessingForm = {
            textAlign: 'center'
        }

        const guessingGame = {
            display: 'block',
            marginLeft: 'auto',
            marginRight: 'auto',
            marginTop: '15%'
        }

        const pokemonImage = {
            borderRadius: '50%',
            backgroundColor: 'lightgray',
            padding: '3%',
            marginLeft: 'auto',
            marginRight: 'auto',
            marginTop: '5%',
            display: 'block'
        }

        return (
            <div style={guessingGame} className='guessingDiv'>
                <img src={this.state.sprite} style={pokemonImage} alt='pokemon' />
                <h2 style={{ textAlign: 'center' }}>Which Pokemon is this?</h2>
                <form onSubmit={this.handleSubmit} style={guessingForm}>
                    <input style={{ padding: '1%' }} type="text" value={this.state.value} onChange={this.handleChange} />
                    <input style={{ padding: '1.5%', backgroundColor: '#FF4D4D', border: 'none', color: 'white' }} type="submit" value="GUESS" />
                </form>
                <h4 style={{ textAlign: 'center' }}>{this.props.score}/151 GUESSED</h4>
            </div>
        )
    }
}

export default GuessingGame

А это мое приложение. js

import React, { Component } from 'react';
import PokemonList from './components/PokemonList.js';
import GuessingGame from './components/GuessingGame.js';
import './App.css';
// import ProgressBar from './ProgressBar';

class App extends Component {
  constructor() {
    super();
    this.state = {
      pokemon: null,
      showPokedex: false,
      score: 0,
      name: '',
      url: '',
      sprite: '',
      proxyurl: `https://cors-anywhere.herokuapp.com/`,
      pokemonUrl: `http://pokeapi.co/api/v2/pokemon?limit=151`
    }
    this.handleClick = this.handleClick.bind(this);
  }

  //fetch the pokemon data from the pokeapi and randomize an id of pokemon the user will have to guess
  componentDidMount() {
    this.fetchData()
  }

  fetchData = (score) => {
    //had to add proxy url because of No Access-Control-Allow-Origin error and call fetch like this: (fetch(proxyurl + pokemonUrl))
    fetch(this.state.proxyurl + this.state.pokemonUrl)
      .then(res => res.json())
      .then(data => {
        let randomId = Math.floor(Math.random() * data['results'].length)
        this.setState({
          pokemon: data.results,
          name: data.results[randomId - 1].name,
          url: data.results[randomId - 1].url,
          score: score ? this.state.score + 1 : this.state.score,
        });
        console.log(this.state.name)
      })
      .catch(err => console.log(err));
  }

  //on click show or close pokedex
  handleClick() {
    this.setState({ showPokedex: !this.state.showPokedex });
  }

  render() {

    //homepage 
    const Home = () => {
      const header = {
        backgroundColor: '#FF4D4D',
        textAlign: 'center',
        color: 'white',
        borderBottom: '5px solid black',
        padding: '5%',
        margin: '0',
        position: 'fixed',
        width: '100%'
      }

      const pokedexButton = {
        border: '4px solid black',
        backgroundColor: '#FF4D4D',
        width: '85px',
        height: '80px',
        color: 'white',
        borderRadius: '50%',
        position: 'fixed',
        top: '20%',
        right: '5%'
      }

      return (
        <>
          <h1 style={header}>Who's That Pokémon?</h1>
          <GuessingGame
            pokemon={this.state.pokemon}
            name={this.state.name}
            url={this.state.url}
            score={this.state.score}
            fetchData={this.fetchData}
            proxyurl={this.state.proxyurl}
            pokemonUrl={this.state.pokemonUrl} />
          {this.state.showPokedex &&
            <PokemonList
              pokemon={this.state.pokemon} />}
          <button type="button" onClick={this.handleClick} style={pokedexButton} className='pokedexBtn'>POKEDEX</button>
        </>
      )
    }
    return (
      <div>
        <div className="pokedex">
        </div>
        <Home />
      </div>
    );
  }
}
export default App;

ProgressBar.jsx

import React from 'react';

const ProgressBar = (props) => {
  return (
    <div className="progress-bar">
      {props.percentage}
      <div className="filler" style={{ width: `${props.percentage}%` }} />
    <div class="progress-bar" role="progressbar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">25%</div>
  </div>
  )
}

export default ProgressBar;

Большое спасибо за вашу помощь.

1 Ответ

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

Предполагая, что ваш score является текущим правильным счетом 151 покемона, следующее даст вам процент от этого.

const percentCorrect = (this.state.score * 100) / 151;

Это, скорее всего, даст вам не очень красиво отформатированное число, то есть 25.3989854839453, поэтому я предпочитаю форматировать его при отображении.

Number(percentCorrect).toFixed(2); // '25.40' notice it is now a string

Теперь, чтобы отобразить индикатор выполнения, необходимо обеспечить несколько вещей:

  • bootstrap и react-bootstrap зависимости
  • импорт или добавление bootstrap CSS где-нибудь в вашем приложении

Импорт индикатора выполнения и создание экземпляра:

import ProgressBar from "react-bootstrap/ProgressBar";
import "bootstrap/dist/css/bootstrap.min.css";

...

  <ProgressBar
    now={percentCorrect}
    label={`${Number(percentCorrect).toFixed(2)}%`}
  />

Edit ProgressBarDemo

РЕДАКТИРОВАТЬ Факторинг / Компонентация "Percent Bar"

PercentBar.jsx

import React from "react";
import PropTypes from "prop-types";
import ProgressBar from "react-bootstrap/ProgressBar";
import "bootstrap/dist/css/bootstrap.min.css";

const propTypes = {
  percent: PropTypes.number.isRequired,
};

const PercentBar = ({ percent, ...props }) => (
  // spread extra props first to prohibit overriding prop values
  <ProgressBar {...props} now={percent} min={0} max={100} />
);

PercentBar.propTypes = propTypes;

export default PercentBar;

Использование

<PercentBar label={percentCorrectLabel} percent={percentCorrect} />
...