Javascript 无限滚动条复制列表结果[ReactJS]
所以我正在做一个pokedex项目,这个项目与PokeAPI相连。我有加载列表的主页,PokemonList.js的代码如下:Javascript 无限滚动条复制列表结果[ReactJS],javascript,reactjs,Javascript,Reactjs,所以我正在做一个pokedex项目,这个项目与PokeAPI相连。我有加载列表的主页,PokemonList.js的代码如下: import React, { Component } from "react"; import PokemonCard from "./PokemonCard"; import axios from "axios"; import InfiniteScroll from "react-infinite-scroller"; export default class
import React, { Component } from "react";
import PokemonCard from "./PokemonCard";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
export default class PokemonList extends Component {
state = {
url: "https://pokeapi.co/api/v2/pokemon?limit=20&offset=0.",
pokemon: null,
itemsCountPerPage: 20,
activePage: 1,
count: 365,
previous: null
};
loadPokemon = () => {
axios
.get(this.state.url)
.then(res => {
this.setState(prevState => {
return {
pokemon: [...prevState.pokemon, ...res.data.results],
url: res.data.next
};
});
})
.catch(function(error) {
// handle error
console.log(error);
});
};
async componentDidMount() {
const res = await axios.get(this.state.url);
this.setState({ pokemon: res.data["results"] });
}
render() {
console.log(this.state.pokemon);
return (
<React.Fragment>
{this.state.pokemon ? (
<div className="row">
<InfiniteScroll
pageStart={1}
loadMore={this.loadPokemon}
hasMore={true}
loader={
<div className="loader" key={0}>
Loading ...
</div>
}
>
{this.state.pokemon.map((pokemon, i) => (
<PokemonCard
key={pokemon.name + i}
name={pokemon.name}
url={pokemon.url}
/>
))}
</InfiniteScroll>
</div>
) : (
<h1>Loading Pokemon</h1>
)}
</React.Fragment>
/*<React.Fragment>
{this.state.pokemon ? (
<div className="row">
{this.state.pokemon.map(pokemon => (
<PokemonCard
key={pokemon.name}
name={pokemon.name}
url={pokemon.url}
/>
))}
</div>
) : (
<h1>Loading Pokemon</h1>
)}
</React.Fragment>*/
);
}
}
import React,{Component}来自“React”;
从“/PokemonCard”导入PokemonCard;
从“axios”导入axios;
从“反应无限滚动条”导入无限滚动条;
导出默认类PokemonList扩展组件{
状态={
url:“https://pokeapi.co/api/v2/pokemon?limit=20&offset=0.",
口袋妖怪:空,
项目浏览每页:20,
活动页面:1,
计数:365,
上一个:空
};
loadPokemon=()=>{
axios
.get(this.state.url)
。然后(res=>{
this.setState(prevState=>{
返回{
口袋妖怪:[…prevState.pokemon,…res.data.results],
url:res.data.next
};
});
})
.catch(函数(错误){
//处理错误
console.log(错误);
});
};
异步组件didmount(){
const res=await axios.get(this.state.url);
this.setState({pokemon:res.data[“results”]});
}
render(){
log(this.state.pokemon);
返回(
{this.state.pokemon(
{this.state.pokemon.map((pokemon,i)=>(
))}
) : (
装载口袋妖怪
)}
/*
{this.state.pokemon(
{this.state.pokemon.map(pokemon=>(
))}
) : (
装载口袋妖怪
)}
*/
);
}
}
出于某种原因,前20个Pokemoncard是从API加载的,但当我到达第20个时,无限滚动器会再次加载前20个,最后加载下一个20-40,然后再加载40-60。只有第一个设置的金额是重复的
这是返回的控制台的屏幕截图
如您所见,Bulbasaur在列表中的第20个数据之后重复出现。我最终将状态从
pokemon: null,
到
我补充说
const pokemon = prevState.pokemon;
对于componentDidMount函数中的my loadPokemon函数,您需要设置this.state.url,就像每次调用loadPokemon时一样。当前,您正在为第一个页面调用两次基本url,一次在componentDidMount中,另一次在loadPokemon中 您不应该在
组件didmount()
中调用loadPokemon
函数。卸下它,它将按预期工作
import React, { Component } from "react";
import PokemonCard from "./PokemonCard";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
export default class PokemonList extends Component {
state = {
url: "https://pokeapi.co/api/v2/pokemon?limit=20&offset=0.",
pokemon: [],
itemsCountPerPage: 20,
activePage: 1,
count: 365,
previous: null
};
loadPokemon = () => {
axios
.get(this.state.url)
.then(res => {
this.setState(prevState => {
return {
pokemon: [...prevState.pokemon, ...res.data.results],
url: res.data.next
};
});
})
.catch(function(error) {
// handle error
console.log(error);
});
};
render() {
console.log(this.state.pokemon);
return (
<React.Fragment>
{this.state.pokemon ? (
<div className="row">
<InfiniteScroll
pageStart={1}
loadMore={this.loadPokemon}
hasMore={true}
loader={
<div className="loader" key={0}>
Loading ...
</div>
}
>
{this.state.pokemon.map((pokemon, i) => (
<PokemonCard
key={pokemon.name + i}
name={pokemon.name}
url={pokemon.url}
/>
))}
</InfiniteScroll>
</div>
) : (
<h1>Loading Pokemon</h1>
)}
</React.Fragment>
);
}
}
import React,{Component}来自“React”;
从“/PokemonCard”导入PokemonCard;
从“axios”导入axios;
从“反应无限滚动条”导入无限滚动条;
导出默认类PokemonList扩展组件{
状态={
url:“https://pokeapi.co/api/v2/pokemon?limit=20&offset=0.",
口袋妖怪:[],
项目浏览每页:20,
活动页面:1,
计数:365,
上一个:空
};
loadPokemon=()=>{
axios
.get(this.state.url)
。然后(res=>{
this.setState(prevState=>{
返回{
口袋妖怪:[…prevState.pokemon,…res.data.results],
url:res.data.next
};
});
})
.catch(函数(错误){
//处理错误
console.log(错误);
});
};
render(){
log(this.state.pokemon);
返回(
{this.state.pokemon(
{this.state.pokemon.map((pokemon,i)=>(
))}
) : (
装载口袋妖怪
)}
);
}
}
检查此选项可能会有所帮助you@KishanJaiswal出于某种原因,这似乎并没有解决问题。如果您的api响应是这样的,请查看它给出的下一个20或更多的响应not@KishanJaiswal所以它加载最初的20,当我到达底部时,它再次预加载前20,然后加载20-40,然后加载40-60,依此类推。这不是一个有效的解决方案。您只需删除组件didmount
,一切都会解决;)@JulienRioux这个解决方案或多或少是你建议的最后一个解决方案,所以我会把你的答案标记为正确答案。我不需要或不需要删除componentDidMount
import React, { Component } from "react";
import PokemonCard from "./PokemonCard";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
export default class PokemonList extends Component {
state = {
url: "https://pokeapi.co/api/v2/pokemon?limit=20&offset=0.",
pokemon: [],
itemsCountPerPage: 20,
activePage: 1,
count: 365,
previous: null
};
loadPokemon = () => {
axios
.get(this.state.url)
.then(res => {
this.setState(prevState => {
return {
pokemon: [...prevState.pokemon, ...res.data.results],
url: res.data.next
};
});
})
.catch(function(error) {
// handle error
console.log(error);
});
};
render() {
console.log(this.state.pokemon);
return (
<React.Fragment>
{this.state.pokemon ? (
<div className="row">
<InfiniteScroll
pageStart={1}
loadMore={this.loadPokemon}
hasMore={true}
loader={
<div className="loader" key={0}>
Loading ...
</div>
}
>
{this.state.pokemon.map((pokemon, i) => (
<PokemonCard
key={pokemon.name + i}
name={pokemon.name}
url={pokemon.url}
/>
))}
</InfiniteScroll>
</div>
) : (
<h1>Loading Pokemon</h1>
)}
</React.Fragment>
);
}
}