[英]The state changed but the render method from react does not trigger
我目前正在自学代码,目前正在深入研究 React.js。 我正在构建一个简单的应用程序,它显示通过 punkAPI ( https://punkapi.com/documentation/v2 ) 提取的啤酒信息。
在我的应用程序中,我想添加某种“无限”滚动,当用户到达页面底部时,它会从 API 中提取更多数据。
目前,handleScroll 方法工作,并更新组件的状态,但它不会触发渲染方法,我想知道为什么。
我意识到我的代码有很多问题,我打算重新构造它,在 this.state 中添加一些布尔值以检查是否还有更多数据要加载,处理错误并不会如此密集地触发 handleScroll 方法.
但是,我仍然想知道为什么即使状态更新了也没有渲染发生。
class BeerList extends Component {
constructor() {
super()
this.state = {
loading: false,
beers: []
}
this.handleScroll = this.handleScroll.bind(this)
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll, true);
this.setState({
loading: true
})
fetch("https://api.punkapi.com/v2/beers?per_page=12")
.then(response => response.json())
.then(data => {
this.setState({
loading: false,
beers: data
})
})
}
handleScroll() {
const checkForNewBeers = () => {
let lastBeerCard = document.querySelector(".beer-list > div:last-child");
let lastBeerCardOffset = lastBeerCard.offsetTop + lastBeerCard.clientHeight;
let pageOffset = window.pageYOffset + window.innerHeight;
if (pageOffset <= lastBeerCardOffset - 10) {
return;
}
this.setState(prevState => {
const beers = prevState.beers;
const page = (prevState.beers.length / 12) + 1;
fetch(`https://api.punkapi.com/v2/beers?per_page=12&page=${page}`)
.then(response => response.json())
.then(data => {
for (let item of data) {
beers.push(item);
}
console.log({
beers: beers
});
return {
beers: beers
}
});
});
}
document.addEventListener("scroll", function (event) {
checkForNewBeers();
});
}
render() {
let beerCards = []
if (this.state.beers.length > 0) {
beerCards = this.state.beers.map(beer => {
return <BeerCard
key = {
beer.id
}
img = {
beer.image_url
}
title = {
beer.name
}
description = {
beer.description
}
/>
})
}
return ( <
div className = "container" >
<
div className = "row beer-list" > {
beerCards
} <
/div> < /
div >
)
}
}
export default BeerList
因此,当页面加载时正确附加 BeerCards,然后当您滚动控制台时,会显示状态已更新(太多但仍然如此)。 我希望页面加载大量 BeerCards,但什么也没发生。 这是为什么?
一旦调用 setState 中的最后一个语句 fetch,就会返回一个 undefined。 尝试将 setState 参数转换为异步函数:
this.setState(async prevState => {
const beers = prevState.beers;
const page = prevState.beers.length / 12 + 1;
let response = await fetch(
`https://api.punkapi.com/v2/beers?per_page=12&page=${page}`
);
response = await response.json();
for (const item of response) {
beers.push(item);
}
console.log({
beers: beers
});
return {
beers: beers
};
});
不是从异步fetch
返回一个对象,而是在.then()
调用setState
let beers = this.state.beers;
const page = (this.state.beers.length / 12) + 1;
fetch(`https://api.punkapi.com/v2/beers?per_page=12&page=${page}`)
.then(response => response.json())
.then(data => {
for (let item of data) {
beers.push(item);
}
this.setState({ beers });
});
你离得那么近! 通过简单地在“this.setState”中的“prevState”前面添加关键字“async”,在“fetch”前面添加“return await”,您的应用程序的状态应该被更新并按预期触发重新渲染。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.