我在哪里在reactjs中添加click事件

时间:2018-05-01 11:15:29

标签: reactjs onclick

也许这看起来不像代码,但有什么方法可以在点击时更改其他组件的值/状态?

import React from 'react';
import './pokemonList.css';
import {Component} from 'react';
import Pokemon from './Pokemon';    
 class PokemonList extends Component {
  constructor(props){
    super(props);
    this.state = {
      pokemons : [],
      pokemon : {}
    };
  }
  componentWillMount(){
    fetch('https://pokeapi.co/api/v2/pokemon/').then(res=>res.json())
    .then(response=>{
      this.setState({
        pokemons : response.results,
      });
    });
  }    
handleClick(id) {
  fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)
      .then(res => res.json())
      .then(data => {
        const pokemon = new Pokemon(data);    
        this.setState({ pokemon: pokemon });
      })
      .catch(err => console.log(err));
    console.log("click happened");
}
render(){
    const {pokemons} = this.state; 
    return (
    <div className='pokemonList'> {pokemons.map(pokemon =>(
         <button onClick={this.handleClick.bind(this)} className='pokemon- 
         btn' key={pokemon.name}>
          {pokemon.name}
        </button>
        ))}
      </div> 
      )
}}
export default PokemonList;

此时我甚至不确定handleClick()必须在哪里,所以我把它放在我的App组件中。输出没问题,但点击这些按钮似乎什么也没做。他们应该在组件中显示详细的口袋妖怪信息。

import React, {Component} from 'react';
import './pokemon-info.css';
const PokemonInfo = ({ pokemon }) => {
  const { name, 
          height, 
          weight, 
          sprite, 
          statsSpeed, 
          statsSpecialDefense, 
          statsSpecialAttack, 
          statsDefense, 
          statsAttack, 
          statsHp 
        } = pokemon;
  return (
    <section className="pokemonInfo">
      <img src={sprite} className='sprite-image' alt="pokemon_sprite"/>
      <div className='data-wrapper'>
        <h3 className="data-char">{pokemon.name}</h3><br />
        <p className = 'data-char'>Height: {height}</p>
        <p className = 'data-char'>Weight: {weight}</p><br />
        <p className = 'data-char'>Stats: </p><br />
        <p className = 'data-char'>Speed: {statsSpeed}</p>
        <p className = 'data-char'>Special defense: {statsSpecialDefense}</p>
        <p className = 'data-char'>Special attack: {statsSpecialAttack}</p>
        <p className = 'data-char'>Defense: {statsDefense}</p>
        <p className = 'data-char'>Attack: {statsAttack}</p>
        <p className = 'data-char'>Hp: {statsHp}</p>
      </div>
    </section>
  )
}
export default PokemonInfo;

这是我的App组件

import React, { Component } from 'react';
import './App.css';
import PokemonList from './PokemonList';
import Pokemon from './Pokemon';
import PokemonInfo from './PokemonInfo';
class App extends Component {
 constructor() {
    super();
    this.state = {
      pokemon: {}
    };
    this.handleOnClick = this.handleOnClick.bind(this);
  }
  handleOnClick(id) {
    fetch(`http://pokeapi.co/api/v2/pokemon/${id}/`)
      .then(res => res.json())
      .then(data => {
        const pokemon = new Pokemon(data);
        this.setState({ pokemon });
      })
      .catch(err => console.log(err));
  }
  render() {
    return (
      <div className="App">
        <PokemonList />
        <PokemonInfo pokemon={this.state.pokemon}/>
      </div>
    );
  }
}
export default App;

显然我确实在某个地方出了问题,但在哪里?

更新

口袋妖怪

class Pokemon {
  constructor(data) {
this.id = data.id;
this.name = data.name;
this.height = data.height;
this.weight = data.weight;
this.sprite = data.sprites.front_default;
this.statsSpeed = data.stats[0].stats.base_stat;
this.statsSpecialDefense = data.stats[1].stats.base_stat;
this.statsSpecialAttack = data.stats[2].stats.base_stat;
this.statsDefense = data.stats[3].stats.base_stat;
this.statsAttack = data.stats[4].stats.base_stat;
this.statsHp = data.stats[5].stats.base_stat;
  }
}
export default Pokemon;

1 个答案:

答案 0 :(得分:0)

您的App组件应该保持状态并将更新程序函数作为道具传递给子组件:

<强> PokemonList

import React from "react";
import "./pokemonList.css";
import { Component } from "react";
import Pokemon from "./Pokemon";
class PokemonList extends Component {    
  render() {
    const { pokemons } = this.props;
    return (
      <div className="pokemonList">
        {pokemons.map(pokemon => (
          <button
            onClick={() => this.props.handleClick(pokemon.id)} // id or whatever prop that is required for request
            className="pokemon-btn"
            key={pokemon.name}
          >
            {pokemon.name}
          </button>
        ))}
      </div>
    );
  }
}

PokemonInfo - 此处无变化。

APP

import React, { Component } from "react";
import "./App.css";
import PokemonList from "./PokemonList";
import Pokemon from "./Pokemon";
import PokemonInfo from "./PokemonInfo";
class App extends Component {
  constructor() {
    super();
    this.state = {
      pokemon: {},
      pokemons: [],
    };
    this.handleOnClick = this.handleOnClick.bind(this);
  }

  componentDidMount() {
    fetch("https://pokeapi.co/api/v2/pokemon/")
      .then(res => res.json())
      .then(response => {
        this.setState({
          pokemons: response.results
        });
      });
  }

  handleOnClick(id) {
    fetch(`http://pokeapi.co/api/v2/pokemon/${id}/`)
      .then(res => res.json())
      .then(data => {
        const pokemon = new Pokemon(data);
        this.setState({ pokemon });
      })
      .catch(err => console.log(err));
  }
  render() {
    return (
      <div className="App">
        <PokemonList pokemons={this.state.pokemons} handleClick={this.handleOnClick} />
        <PokemonInfo pokemon={this.state.pokemon} />
      </div>
    );
  }
}

更多关于lifting the state up