Возможно, это даже не похоже на код, но есть ли способ изменить значение / состояние других компонентов при нажатии?
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.info(err));
console.info("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 (), поэтому я также поместил его в свой компонент приложения. Результат в порядке, но нажатие на эти кнопки, похоже, ничего не делает. Они должны отображать подробную информацию о покемонах в компоненте.
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;
Вот мой компонент приложения
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.info(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;
Компонент 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>
);
}
}
ПокемонИнфо - здесь без изменений.
ПРИЛОЖЕНИЕ
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.info(err));
}
render() {
return (
<div className = "App">
<PokemonList pokemons = {this.state.pokemons} handleClick = {this.handleOnClick} />
<PokemonInfo pokemon = {this.state.pokemon} />
</div>
);
}
}
Подробнее о поднять состояние.
Может быть проблема, что этот ссылка на сайт имеет строку JSON только с двумя свойствами: url и name? Но мне нужно обновить свой компонент PokemonInfo из информации, приведенной, например, из ссылка на сайт
Я проверю это позже
@SergeyShpironok http://pokeapi.co/api/v2/pokemon/${id}/
возвращает (как вы написали) только name
и url
, поэтому конструктор Pokemon
не работает, поскольку нет свойства sprites
, из которого можно получить front_default
.
насколько я понимаю мне нужно fetch
данные отсюда fetch("https://pokeapi.co/api/v2/pokemon/")
как-то используя свойство url
? Возможно ли извлечение из полученных данных?
Это немного выходит за рамки этого вопроса. Вам нужно как-то получить полные данные для создания объекта Pokemon. Вы можете сделать это с помощью обещаний.
Это странно, вроде бы сейчас все в порядке, но этот щелчок не меняет компонент PokemonInfo. Консоль сообщает: «TypeError: невозможно прочитать свойство 'front_default' undefined в новом Pokemon (Pokemon.js: 7) в App.js: 30» Может быть, что-то не так с моим компонентом Pokemon