路由问题并重新渲染React组件

时间:2020-04-11 17:00:28

标签: javascript reactjs react-router components render

我从反应开始,我正在使用pokeApi开发一个pokedex,发现有人在做一个视频,我已经适应了我的想法,但是我在重新渲染组件时遇到问题... 我将导航栏放在左侧,当我单击神奇宝贝的卡片时,右侧会显示一个组件,其中包含该神奇宝贝的所有信息

当我单击其他口袋妖怪时,路线正在改变,但仍然存在相同的组件,我必须更新页面以获取与路线匹配的实际口袋妖怪

这是我来自app.js的代码,也是我导航栏中的pokemonCard(PokemonTarjeta)的代码

App.js

  render(){
    return (
      <Router>
        <div className = "App">
          <NavBar />
          <Switch>
            <Route exact path="/:pokemonIndex" component={Pokemon}/>
          </Switch>
        </div>

      </Router>

    );
  }
}

PokemonCard.js


  state = {
    name: '',
    imageUrl: '',
    pokemonIndex: '',
    imageLoading: true,
    toManyRequest: false
  };

  componentDidMount(){
    const {name, url} = this.props;
    const pokemonIndex = url.split("/")[url.split("/").length - 2];
    const imageUrl = `https://github.com/pokeAPI/sprites/blob/master/sprites/pokemon/${pokemonIndex}.png?raw=true`;

    this.setState({
      name,
      imageUrl,
      pokemonIndex,
    });
  }

  render(){
    return (
      <StyledLink to={`${this.state.pokemonIndex}`}>
        <Tarjeta className="tarjeta">
          <div className="card">
            {this.state.imageLoading ? (<img src={spinner} style={{width:"5em", height:"5em"}}className="card-img-top rounded d-block mt-2" alt="Pokemon" />) : null}
            <div className="card-body row">
              <div className="col-md-4">
              <Sprite
                className="rounded mx-auto"
                onLoad={() => this.setState({imageLoading : false})}
                onError={() => this.setState({toManyRequest : true})}
                src={this.state.imageUrl}
                style={
                  this.state.toManyRequest ? {display: "none"} :
                  this.state.imageLoading ?
                  null : {display: "block"}
                }>
              </Sprite>
              {this.state.toManyRequest ? (<h6 className="mx-auto"><span className="badge badge-danger mt-2">To many request</span></h6>) : null}
              </div>
              <div className="col-md-8 mt-4 mx-auto">
                <h5 className="card-title">
                {this.state.pokemonIndex}-
                {this.state.name
                  .toLowerCase()
                  .split(" ")
                  .map(
                    letter => letter.charAt(0).toUpperCase() + letter.substring(1)
                  )
                  .join(" ")}
                </h5>
              </div>
            </div>
          </div>
        </Tarjeta>
      </StyledLink>

    );
  }
}

这是Pokemon.js代码,以备不时之需

  state = {
    name: '',
    pokemonIndex: '',
    imageUrlFront: '',
    imageUrlShiny: '',
    types: [],
    description: '',
    stats: {
      hp: '',
      attack: '',
      defense: '',
      speed: '',
      specialAttack: '',
      specialDefense: ''
    },
    height: '',
    weight: '',
    eggGroup: '',
    abilities: '',
    genderRatioMale: '',
    genderRatioFemale: '',
    evs: '',
    hatchSteps: ''
  };

  async componentDidMount() {
    const {pokemonIndex} = this.props.match.params;
    //url para pokemones
    const pokemonUrl = `https://pokeapi.co/api/v2/pokemon/${pokemonIndex}/`;
    const pokemonSpeciesUrl = `https://pokeapi.co/api/v2/pokemon-species/${pokemonIndex}/`;
    //informacion del pokemones
    const pokemonRes = await axios.get(pokemonUrl);
    const name = pokemonRes.data.name;
    const imageUrlFront = `https://projectpokemon.org/images/normal-sprite/${name}.gif`;
    const imageUrlShiny = `https://projectpokemon.org/images/shiny-sprite/${name}.gif`;

    let {hp, attack, defense, speed, specialAttack, specialDefense} = '';
    pokemonRes.data.stats.map(stat => {
      switch(stat.stat.name){
        case 'hp': hp = stat['base_stat']; break;
        case 'attack': attack = stat['base_stat']; break;
        case 'defense': defense = stat['base_stat']; break;
        case 'speed': speed = stat['base_stat']; break;
        case 'special-attack': specialAttack = stat['base_stat']; break;
        case 'special-defense': specialDefense = stat['base_stat']; break;

      }
    });

    const height = Math.round((pokemonRes.data.height * 0.328084 + 0.0001) * 100) / 100;
    const weight = Math.round((pokemonRes.data.weight * 0.220462 + 0.1) * 100) / 100;
    let types = pokemonRes.data.types.map(type => type.type.name);
    const abilities = pokemonRes.data.abilities.map(ability => {
      return ability.ability.name.toLowerCase().split("-").map(s => s.charAt(0).toUpperCase() + s.substring(1)).join(" ");
    });
    const evs = pokemonRes.data.stats.filter(stat =>{
      if (stat.effort > 0) {
        return true;
      }
      else{ return false; }
    }).map(stat =>{
      return `${stat.effort} ${stat.stat.name}`.toLowerCase().split("-").map(s => s.charAt(0).toUpperCase() + s.substring(1)).join(" ");
    }).join(', ');

    await axios.get(pokemonSpeciesUrl).then(res =>{
      let description = '';
      res.data.flavor_text_entries.some(flavor =>{
        if (flavor.language.name === 'es') {
          description = flavor.flavor_text;
          return;
        }
      });
      const femaleRate = res.data['gender_rate'];
      const genderRatioFemale = 12.5 * femaleRate;
      const genderRatioMale = 12.5 * (8 - femaleRate);
      const catchRate = Math.round((100/255) * res.data['capture_rate']);
      const eggGroup = res.data['egg_groups'].map(group =>{
        return group.name.toLowerCase().split("-").map(s => s.charAt(0).toUpperCase() + s.substring(1)).join(" ");
      })
      .join(', ');
      const hatchSteps = 255 * (res.data['hatch_counter'] + 1);
      this.setState({
        description,
        genderRatioFemale,
        genderRatioMale,
        catchRate,
        eggGroup,
        hatchSteps
      });
    });


    this.setState({
      name,
      pokemonIndex,
      imageUrlFront,
      imageUrlShiny,
      types,
      stats:{
        hp,
        attack,
        defense,
        speed,
        specialAttack,
        specialDefense,
      },
      height,
      weight,
      abilities,
      evs
    });

  }

我尝试了不同的方法,但仍未找到解决方案...

1 个答案:

答案 0 :(得分:0)

我认为您在componentDidMount中通过道具设置状态而在道具更改时不更新状态的问题。