You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:36:18