React中useEffect内使用fetch获取数据,状态无法更新
问题解决:React useEffect获取后端数据后state未更新
你的问题核心出在fetch配置里的mode: "no-cors",这会导致浏览器禁止你读取响应内容——哪怕网络面板显示收到了后端返回的数据,前端也拿不到实际值,自然setItems后items还是空。
步骤1:移除mode: "no-cors"
直接删掉这个配置项,它只适用于不需要读取响应的场景(比如加载第三方图片),完全不适合你需要获取后端数据的需求。
步骤2:给Spring Boot配置跨域支持
前端(默认3000端口)和后端(8080端口)属于不同域名,浏览器会触发跨域拦截,必须在后端开启CORS允许前端访问:
方式一:全局配置(推荐)
新建一个配置类:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") // 匹配你的接口路径 .allowedOrigins("http://localhost:3000") // 允许前端域名 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); } }
方式二:局部配置
在你的Controller类或方法上添加@CrossOrigin注解:
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") @CrossOrigin(origins = "http://localhost:3000") public class HelloController { @GetMapping("/hellotxt") public String getHelloTxt() { return "Hello from Spring Boot!"; } }
步骤3:优化fetch代码(可选,让逻辑更清晰)
你现在混用了async/await和.then(),可以统一成一种写法,同时加上错误处理方便排查问题:
import { useEffect, useState } from "react"; export default function Home() { const [items, setItems] = useState(""); const [nrOfClick, setNrOfClicks] = useState(0); useEffect(() => { const fetchData = async () => { try { const response = await fetch("http://localhost:8080/api/hellotxt"); if (!response.ok) { throw new Error(`请求失败:${response.status}`); } const data = await response.text(); setItems(data); } catch (error) { console.error("获取数据出错:", error); } }; fetchData(); }, []); return ( <div className="App"> <h1>This is the home page</h1> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> <p className="App-intro"> Fetch data from spring-boot server: <code>{items}</code> </p> <p> Number of clicks <code>{nrOfClick}</code> </p> <button onClick={() => setNrOfClicks(nrOfClick + 1)}>Click ME</button> </div> ); }
做完以上步骤,重新启动前后端,就能正常获取数据并更新state了。
内容的提问来源于stack exchange,提问作者devios
相关产品推荐
相关产品推荐

