React新闻应用点击Next按钮报错:Cannot read properties of undefined (reading 'state')
新闻应用Next按钮点击报错修复方案
错误详情
点击Next按钮触发报错:
News.js:16 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'state')
错误发生在handleNextClick事件的URL拼接环节,目标是加载第2页新闻,尝试过bind方法绑定this但无效。
问题根源
代码中所有访问页码的地方都写错了语法:错误使用this.page.state来获取当前页码,正确写法应为this.state.page。this.page本身是undefined,读取它的state属性必然抛出错误。
此外还有几处次要问题:
componentDidMount中URL的page参数错误写成this.page.state+1,初始加载应使用this.state.page(即1)而非+1handlePreviousClick中URL的page参数错误,应为this.state.page - 1而非this.page.state+1handleNextClick中的判断条件逻辑混乱,应先计算目标页码再做边界比较- API返回的总结果数字段是
totalResults(驼峰命名),代码中错误写成totalresults
修正后的完整代码
import React, { Component } from "react"; import Newsitem from "./Newsitem"; export class News extends Component { constructor(props) { super(props); this.state = { articles: [], loading: false, page: 1 }; } async componentDidMount() { let url = `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey&page=${this.state.page}&pagesize=${this.props.pagesize}`; let data = await fetch(url); let parsedData = await data.json(); console.log(parsedData); this.setState({ articles: parsedData.articles, totalresults: parsedData.totalResults }); } handleNextClick = async () => { console.log("next"); const targetPage = this.state.page + 1; const maxPage = Math.ceil(this.state.totalresults / this.props.pagesize); if (targetPage <= maxPage) { let url = `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey&page=${targetPage}&pagesize=${this.props.pagesize}`; let data = await fetch(url); let parsedData = await data.json(); console.log(parsedData); this.setState({ page: targetPage, articles: parsedData.articles }); } }; handlePreviousClick = async () => { console.log("Previous"); const targetPage = this.state.page - 1; let url = `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey&page=${targetPage}&pagesize=${this.props.pagesize}`; let data = await fetch(url); let parsedData = await data.json(); console.log(parsedData); this.setState({ page: targetPage, articles: parsedData.articles }); }; render() { return ( <div className="container my-4 "> <h1 className="text-center">NewsMonkey - TOP Headlines</h1> <div className="row"> {this.state.articles.map((element) => { return ( <div className="col-md-4" key={element.url}> <Newsitem title={element.title ? element.title.slice(0, 40) : ""} description={element.description ? element.description.slice(0, 80) : ""} imgUrl={element.urlToImage} newsUrl={element.url} /> </div> ); })} </div> <div className="container d-flex justify-content-between"> <button type="button" disabled={this.state.page <= 1} className="btn btn-dark" onClick={this.handlePreviousClick} > ← Previous </button> <button type="button" disabled={this.state.page + 1 > Math.ceil(this.state.totalresults / this.props.pagesize)} className="btn btn-dark" onClick={this.handleNextClick} > Next → </button> </div> </div> ); } }
关键修正点说明
- 将所有
this.page.state替换为this.state.page,正确访问组件状态中的页码 - 修正
componentDidMount初始加载逻辑,使用this.state.page加载第1页数据 - 调整
handlePreviousClick的URL参数,正确加载上一页内容 - 重构
handleNextClick的判断逻辑,先计算目标页码再做边界校验,代码更清晰 - 修正API返回字段名,匹配实际的
totalResults驼峰命名
内容的提问来源于stack exchange,提问作者Rafia Khurshid
相关产品推荐
相关产品推荐

