因此,我目前正在使用在线提供的PokeApi开发PokeDex。
该项目的代码如下:
import React, { Component } from "react";
import PokemonCard from "./PokemonCard";
import "../ui/PokemonList.css";
import axios from "axios";
export const PokemonList = class PokemonList extends Component {
state = {
url: "https://pokeapi.co/api/v2/pokemon/",
pokemon: null
};
async componentDidMount() {
const res = await axios.get(this.state.url);
this.setState({ pokemon: res.data["results"] });
console.log(res);
}
render() {
return <div></div>;
}
};
export const PokeList = () => {
return (
<React.Fragment>
{this.state.pokemon ? (
<section className="poke-list">
{this.state.pokemon.map(pokemon => (
<PokemonCard />
))}
</section>
) : (
<h1>Loading Pokemon</h1>
)}
</React.Fragment>
);
};
如您所见,我已经在PokemonList Component类中声明了一个状态,但是随后我尝试在变量PokeList中进一步调用它。问题是在PokeList
中无法识别状态(我收到错误消息“ TypeError:无法读取未定义的属性'state'”)
我该如何调用上面的类中声明的状态?
-------------------编辑--------------------------- ----
好的,所以我意识到了一些。我有Dashboard.js的代码,该代码显示了我的列表。代码如下
import React, { Component } from "react";
import { PokeList } from "../pokemon/PokemonList";
export default class Dashboard extends Component {
render() {
return (
<div>
<div className="row">
<div className="col">
<PokeList />
</div>
</div>
</div>
);
}
}
当我将代码从PokeList更改为PokemonList时。所以会
import React, { Component } from "react";
import { PokemonList } from "../pokemon/PokemonList";
export default class Dashboard extends Component {
render() {
return (
<div>
<div className="row">
<div className="col">
<PokemonList />
</div>
</div>
</div>
);
}
}
我认为可以从Api那里获得20只神奇宝贝的清单
console.log(this.state.pokemon);。
但是由于我没有在仪表板上显示PokeList,所以所有的Pokemon卡都不会显示。
控制台输出的屏幕截图
答案 0 :(得分:2)
首先,所有功能组件都是无状态的。如果需要维护状态,请使用类组件或挂钩。您不能在另一个组件中使用一个组件的状态。您有两个选择,
答案 1 :(得分:1)
PokemonList和PokeList组件之间有些混淆。我相信您真正想要的只是其中之一。如果将两者混合使用,则可以有一个根据状态控制视图的组件,在这种情况下,状态就是“口袋妖怪”列表。
我在这里混合了两者,因此您的render方法将渲染“ Loading Pokemon”,直到您从axios返回响应为止,然后在响应返回时,它将获取该数据,更新您的状态,并且状态更新触发重新渲染。
import React, { Component } from "react";
import PokemonCard from "./PokemonCard";
import axios from "axios";
class PokemonList extends Component {
state = {
url: "https://pokeapi.co/api/v2/pokemon/",
pokemon: null
};
componentDidMount() {
axios.get(this.state.url).then(res => {
this.setState({ pokemon: res.data["results"] });
});
}
render() {
let pokemonList = <h1>Loading Pokemon</h1>;
const pokemons = this.state.pokemon;
if (pokemons) {
pokemonList = (
<section className="poke-list">
<ul>
{pokemons.map(pokemon => (
<PokemonCard pokemon={pokemon} />
))}
</ul>
</section>
);
}
return <React.Fragment>{pokemonList}</React.Fragment>;
}
}
export default PokemonList;
我还创建了一个简单的PokemonCard组件,在其中列出了API的结果,只是向您展示该方法有效。
import React from "react";
const pokemonCard = props => {
return (
<li key={props.pokemon.name}>
<a href={props.pokemon.url}>{props.pokemon.name}</a>
</li>
);
};
export default pokemonCard;
您可以找到最终的代码,现在将PokeList和PokemonList组合到一个称为PokemonList的组件中:
请记住,如果您的渲染功能依赖于某个状态,则可以确定应该在该组件中管理该状态,或者从父组件中传递该状态。
在您的示例中,我注意到您在状态内设置了url。 URL确实不会改变。这是一个常数,因此您可以轻松地将其从状态中删除并将其放置在变量中,然后只将口袋妖怪列表保留在那里。
例如:
const url = "https://pokeapi.co/api/v2/pokemon/";
state = {
pokemon: null
};
componentDidMount() {
axios.get(url).then(res => {
this.setState({ pokemon: res.data["results"] });
});
}
答案 2 :(得分:0)
import React , { Component } from "react";
import axios from "axios";
//make it as class based component
export default class PokemonList extends Component {
state = {
url: "https://pokeapi.co/api/v2/pokemon/",
pokemon: null
};
async componentDidMount() {
const res = await axios.get(this.state.url);
this.setState({ pokemon: res.data["results"] });
console.log(res);
}
render() {
//check your data here
console.log(this.state.pokemon)
{/*pass data to child*/}
return <div> <PokeList data = { this.state } /> </div>;
}
};
//export this component
export const PokeList = (props) => {
//check your data is coming or not
console.log(props.data)
//access your data from props
return (
<React.Fragment>
{props.data.pokemon ? (
<section className="poke-list">
{props.data.pokemon.map(pokemon => (
pokemon.name
))}
</section>
) : (
<h1>Loading Pokemon</h1>
)}
</React.Fragment>
);
};
答案 3 :(得分:0)
您需要迭代自己的清单,将结果从componentDidMount函数作为道具传递给子组件,然后在子组件Demo
中接收道具。