React Router中Link标签跳转后未显示对应新闻分类页面求助
问题描述
我尝试通过新闻API获取数据,想用React Router展示不同分类的新闻。现在Link标签能修改localhost的URL,但页面不显示对应分类的新闻,求解决。相关代码如下:
App.js
import './App.css'; import React, { Component } from 'react' import Navbar from './COMPONENTS/Navbar'; import News from './COMPONENTS/News'; import { BrowserRouter, Routes, Route, } from "react-router-dom"; export default class App extends Component { render() { return ( <> <BrowserRouter> <Navbar/> <News category="general"/> <Routes> <Route path="/business" element={<News key="business" category="business"/>}></Route> <Route path="/sports" element={<News key="sports" category="sports"/>}></Route> <Route path="/health" element={<News key="health" category="health"/>}></Route> <Route path="/politics" element={<News key="politics" category="politics"/>}></Route> </Routes> </BrowserRouter> </> ) } }
VerticalNav.jsx(包含所有跳转链接)
import React, { Component } from 'react' import { Link } from 'react-router-dom' export default class VerticalNav extends Component { render() { return ( <> <nav className="navbar2"> <ul className="ul_list"> <li className="vertical_comp"> <Link className="avertical_comp" to="/business">Business</Link> </li> <li className="vertical_comp"> <Link className="avertical_comp" to="/sports">Sports</Link> </li> <li className="vertical_comp"> <Link className="avertical_comp" to="/health">Health</Link> </li> </ul> </nav> </> ) } }
News组件(使用props的文件)
import React, { Component } from 'react' import NewsItem from './NewsItem' import Spinner from './Spinner'; import VerticalNav from './Verticalnav'; import PropTypes from 'prop-types'; export default class News extends Component { static defaultProps = { category : 'general', } static propTypes = { category : PropTypes.string, } constructor() { super(); this.state = { article: [], page: 1, loading: false, } } async componentDidMount() { this.setState({ loading: true }) let url = `https://newsapi.org/v2/top-headlines? country=in&category=${this.props.category}& apiKey=6aeca0faebbd45c1a1ec3c463f703ebb`; let data = await fetch(url); let parseData = await data.json(); this.setState({ article: parseData.articles, loading: false }); } handleNext = async () => { let url = `https://newsapi.org/v2/top-headlines? country=in&category=${this.props.category}&apiKey=6aeca0faebb d45c1a1ec3c463f703ebb&page=${this.state.page + 1}`; this.setState({ loading: true }); let data = await fetch(url); let parseData = await data.json(); this.setState({ page: this.state.page + 1, article: parseData.articles, loading: false }) console.log(this.state.page); } handlePrevious = async () => { let url = `https://newsapi.org/v2/top-headlines? country=in&category=${this.props.category}&apiKey=6aeca0faebbd45c1 a1ec3c463f703ebb&page=${this.state.page - 1}`; let data = await fetch(url); let parseData = await data.json(); this.setState({ page: this.state.page - 1, article: parseData.articles, loading: false }) } render() { return ( <> <div className="vertical"> <VerticalNav/> <div class="card1"> <h1 className='mainheading' >THE PAHADI PRESS HEADLINES OF THE DAY</h1> <div class="row row1"> {this.state.loading && <Spinner />} {this.state.article.map((e) => { return <div class="col-md-4 colu" key={e.url} > <NewsItem title={e.title} decription={e.description} imageUrl={e.urlToImage} newsUrl={e.url} newsauthor={e.author} source={e.source.name} /> </div> }) } </div> </div> </div> </> ) } }
修复方案
1. 调整App.js路由结构,移除全局渲染的News组件
你在Routes外部直接渲染了<News category="general"/>,导致该组件始终显示,路由匹配的分类新闻被覆盖。需要把默认分类改成路由的根路径:
import './App.css'; import React, { Component } from 'react' import Navbar from './COMPONENTS/Navbar'; import News from './COMPONENTS/News'; import { BrowserRouter, Routes, Route, } from "react-router-dom"; export default class App extends Component { render() { return ( <> <BrowserRouter> <Navbar/> <Routes> {/* 根路径显示general分类 */} <Route path="/" element={<News key="general" category="general"/>}></Route> <Route path="/business" element={<News key="business" category="business"/>}></Route> <Route path="/sports" element={<News key="sports" category="sports"/>}></Route> <Route path="/health" element={<News key="health" category="health"/>}></Route> <Route path="/politics" element={<News key="politics" category="politics"/>}></Route> </Routes> </BrowserRouter> </> ) } }
2. 给News组件添加props变化监听,重新获取数据
当前News组件仅在componentDidMount时请求一次数据,路由切换导致category props变化时不会重新请求。需要添加componentDidUpdate钩子,并封装请求逻辑复用:
import React, { Component } from 'react' import NewsItem from './NewsItem' import Spinner from './Spinner'; import VerticalNav from './Verticalnav'; import PropTypes from 'prop-types'; export default class News extends Component { static defaultProps = { category : 'general', } static propTypes = { category : PropTypes.string, } constructor() { super(); this.state = { article: [], page: 1, loading: false, } } async componentDidMount() { await this.fetchNews(); } // 监听category props变化,重新请求数据 async componentDidUpdate(prevProps) { if (prevProps.category !== this.props.category) { this.setState({ page: 1 }); await this.fetchNews(); } } // 封装新闻请求逻辑 async fetchNews() { this.setState({ loading: true }); let url = `https://newsapi.org/v2/top-headlines?country=in&category=${this.props.category}&apiKey=6aeca0faebbd45c1a1ec3c463f703ebb&page=${this.state.page}`; let data = await fetch(url); let parseData = await data.json(); this.setState({ article: parseData.articles, loading: false }); } handleNext = async () => { this.setState({ page: this.state.page + 1 }, async () => { await this.fetchNews(); }); } handlePrevious = async () => { if (this.state.page > 1) { this.setState({ page: this.state.page - 1 }, async () => { await this.fetchNews(); }); } } render() { return ( <> <div className="vertical"> <VerticalNav/> <div className="card1"> <h1 className='mainheading' >THE PAHADI PRESS HEADLINES OF THE DAY</h1> <div className="row row1"> {this.state.loading && <Spinner />} {this.state.article.map((e) => { return <div className="col-md-4 colu" key={e.url} > <NewsItem title={e.title} decription={e.description} imageUrl={e.urlToImage} newsUrl={e.url} newsauthor={e.author} source={e.source.name} /> </div> }) } </div> </div> </div> </> ) } }
3. 细节修正
- 把代码中剩余的
class替换为React规范的className handleNext/handlePrevious中,确保page更新后再执行请求,避免数据不一致- 给
handlePrevious添加page大于1的判断,防止请求无效的page=0数据
内容的提问来源于stack exchange,提问作者Ankit
相关产品推荐
相关产品推荐

