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

React中useState结合useEffect与Axios的状态重置问题求助

问题描述

期望获取带有category=business的URL,但网页自动将newsurl状态重置为无分类的初始URL。保存代码时页面会显示带分类的内容,但刷新页面或输入无id的URL后,状态又回到初始值。

用户提供的代码:

let {id}=useParams()

const [newsurl,setNewsurl]=useState(()=>{
  const initialstate="https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee"
  return initialstate;})
//console.log(id);
const [articles, setActicles] = useState([]);
useEffect( ()=>{
  
  if(id === 2)
    console.log("condition")
    setNewsurl("https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee")},[])  

useEffect(() => {
  const getArticles = async () => {
    
    const res = await Axios.get(newsurl);
    setActicles(res.data.articles);
    console.log(res);
  };
  getArticles();
}, []);
useEffect(() => {
  console.log(newsurl)

  // Whatever else we want to do after the state has been updated.
}, [newsurl])


return (<><Newsnavbar />{articles?.map(({title,description,url,urlToImage,publishedAt,source})=>(
  <NewsItem 
title={title} 
desciption={description} 
url={url} 
urlToImage={urlToImage}
publishedAt={publishedAt}
source={source.name} /> 
))  } </>

)

原因分析

  1. 路由参数变化未触发状态更新:第一个useEffect依赖数组为空,仅在组件首次挂载时运行。当页面刷新、路由参数id变化时,该useEffect不会重新执行,无法根据新的id更新newsurl。
  2. 文章请求未跟随状态更新:获取文章的useEffect依赖为空数组,仅在首次挂载时发起一次请求。后续newsurl状态更新后,不会重新请求数据,导致页面内容不更新。
  3. 条件判断语法错误:第一个useEffect中if(id === 2)未用大括号包裹代码块,导致只有console.log("condition")属于条件分支,setNewsurl会被无条件执行,逻辑不符合预期。
  4. 参数类型不匹配:useParams()返回的参数是字符串类型,用id === 2(数字)判断永远不成立,实际应该用id === "2"。

修复方案

步骤1:修正条件判断与依赖监听

给if语句添加大括号,同时将id加入依赖数组,监听路由参数变化,并且修正参数类型判断:

useEffect(() => {
  if (id === "2") {
    console.log("condition");
    setNewsurl("https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee");
  } else {
    // 非目标id时重置为初始URL
    setNewsurl("https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee");
  }
}, [id]);

步骤2:让文章请求跟随状态更新

修改获取文章的useEffect,将newsurl加入依赖数组,确保状态变化时重新请求数据,同时增加错误捕获:

useEffect(() => {
  const getArticles = async () => {
    try {
      const res = await Axios.get(newsurl);
      setActicles(res.data.articles);
    } catch (err) {
      console.error("加载文章失败:", err);
    }
  };
  getArticles();
}, [newsurl]);

步骤3:优化初始状态(可选)

根据初始id直接设置newsurl的初始值,避免首次挂载时的额外状态更新:

const [newsurl, setNewsurl] = useState(() => {
  return id === "2" 
    ? "https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee"
    : "https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee";
});

完整修复后代码

import { useParams } from "react-router-dom";
import { useState, useEffect } from "react";
import Axios from "axios";
import Newsnavbar from "./Newsnavbar";
import NewsItem from "./NewsItem";

const NewsPage = () => {
  const { id } = useParams();

  const [newsurl, setNewsurl] = useState(() => {
    return id === "2" 
      ? "https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee"
      : "https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee";
  });

  const [articles, setActicles] = useState([]);

  useEffect(() => {
    if (id === "2") {
      setNewsurl("https://newsapi.org/v2/top-headlines?country=de&category=business&apiKey=c75d8c8ba2f1470bb24817af1ed669ee");
    } else {
      setNewsurl("https://newsapi.org/v2/top-headlines?country=us&apiKey=c75d8c8ba2f1470bb24817af1ed669ee");
    }
  }, [id]);

  useEffect(() => {
    const getArticles = async () => {
      try {
        const res = await Axios.get(newsurl);
        setActicles(res.data.articles);
      } catch (err) {
        console.error("加载文章失败:", err);
      }
    };
    getArticles();
  }, [newsurl]);

  useEffect(() => {
    console.log(newsurl);
  }, [newsurl]);

  return (
    <>
      <Newsnavbar />
      {articles?.map(({ title, description, url, urlToImage, publishedAt, source }) => (
        <NewsItem
          key={url}
          title={title}
          desciption={description}
          url={url}
          urlToImage={urlToImage}
          publishedAt={publishedAt}
          source={source.name}
        />
      ))}
    </>
  );
};

export default NewsPage;

注:给map渲染的NewsItem添加key属性,避免React列表渲染警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:40:42