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

React项目如何通过API设置默认新闻分类及解决刷新问题

解决React新闻项目刷新页面重置分类的问题

问题描述

我开发了一个通过API获取数据的React新闻项目,点击对应按钮可展示对应分类的新闻(比如点击sports按钮显示体育新闻)。需求是页面首次加载时默认激活All分类,无需点击即可加载全部新闻,但当前实现存在问题:浏览体育新闻时刷新页面,会自动回到全部新闻,该如何解决?

解决方案

核心思路是把当前分类同步到URL的查询参数中,这样刷新页面时可以从URL读取当前分类,而不是每次都默认加载'all'。同时修复原代码中loading状态设置的时序问题,具体修改步骤如下:

  • 新增状态currentCategory,初始值从URL的category查询参数获取,无参数时默认设为'all'
  • 修改fetchValue函数,更新分类状态的同时,通过history.pushState同步更新URL的查询参数
  • 调整useEffect的依赖为currentCategory,当分类变化时自动触发数据请求
  • 可选:给当前激活的分类按钮添加样式,让用户直观看到当前选中的分类

修改后的代码

App组件

import React, { useEffect, useState } from "react";
import SpinnerLoad from './components/SpinnerLoad'
import NewsItem from "./components/NewsItem";
import Category from "./components/data/Category"

const App = () => {
  const [state, setState] = useState([]);
  const [loading, setLoading] = useState(false);
  
  // 从URL查询参数获取初始分类,无参数则默认'all'
  const initialCategory = new URLSearchParams(window.location.search).get('category') || 'all';
  const [currentCategory, setCurrentCategory] = useState(initialCategory);

  const fetchValue = (category) => {
    // 发起请求前先显示加载状态
    setLoading(false);
    fetch(`https://inshorts-api.herokuapp.com/news?category=${category}`)
      .then(res => res.json())
      .then(res => {
        setState(res.data);
        setLoading(true);
        // 更新URL查询参数,同步当前分类
        const searchParams = new URLSearchParams(window.location.search);
        searchParams.set('category', category);
        window.history.pushState({}, '', `${window.location.pathname}?${searchParams}`);
        // 更新当前分类状态
        setCurrentCategory(category);
      })
      .catch((error) => console.log(error));
  };

  const CategoryButton = ({ category }) => (
    <button 
      onClick={() => fetchValue(category)} 
      style={{ 
        textTransform: 'capitalize',
        // 给激活的按钮添加区分样式
        backgroundColor: currentCategory === category ? '#007bff' : 'transparent',
        color: currentCategory === category ? '#fff' : 'inherit',
        border: 'none',
        padding: '8px 16px',
        margin: '0 4px',
        borderRadius: '4px',
        cursor: 'pointer'
      }}
    >
      {category}
    </button>
  );

  // 监听分类变化,自动触发对应请求
  useEffect(() => {
    fetchValue(currentCategory);
  }, [currentCategory])

  return (
    <>
      <div className="header-bg">
        <h1 className="mb-3">News</h1>
        <div className="btns ">
          {Category.map((value, index) => {
            return <CategoryButton category={value} key={index} />;
          })}
        </div>
      </div>

      <div className="news">
        <div className="container">
          <div className="row">
            { 
            !loading 
            ? <SpinnerLoad/>
             :
            state.map((data,index) => {
              return (
                <NewsItem
                  imageUrl={data.imageUrl}
                  author={data.author}
                  title={data.title}
                  content={data.content}
                  date={data.date}
                  key={data.id}
                />
              );
            })
            }
          </div>
        </div>
      </div>
    </>
  );
};
export default App;

NewsItem组件(无需修改)

import React from 'react'
import clock from "../components/assets/img/Clock.svg"
import user from "../components/assets/img/User.svg"

const NewsItem = (props) => {
    const {imageUrl, title, content, date, author} = props

    return (
        <div class="col-lg-4 col-md-6 col-12 p-2">
            <div className="newsItem">
                <img src={imageUrl} alt=''/>
                <div className="itemBody">
                    <p className='title'>{title}</p>
                    <div className="line"></div>
                    <p className='content'>{content}</p>
                    <div className="itemfooter">
                        <h6><img src={clock} alt='clock'/>{date}</h6>
                        <h6><img src={user} alt='user'/>{author}</h6>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default NewsItem

内容的提问来源于stack exchange,提问作者user18134288

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:12:24