Material-UI相关问题:为何代码会执行两次?
问题原因及解决方案
你的代码出现两次请求的核心原因有两个:
- React StrictMode 开发环境特性:Create React App 默认启用了 StrictMode,在开发模式下,它会故意重复调用组件渲染函数、副作用函数等,目的是帮你检测代码里的潜在问题(比如不合理的副作用),生产环境下这个行为会自动消失。
- 组件写法错误:你把
ReadFile当作 React 组件用<ReadFile />调用,但它并不是一个合法的 React 组件——它没有返回 JSX,而且直接在函数内部执行fetch,每次组件渲染时都会跑一遍这个请求,再加上 StrictMode 的重复渲染,就导致了两次请求。
修正方案
方案1:把读取逻辑放到 useEffect 钩子中
如果 ReadFile 只是个工具函数,不要当作组件调用,而是在组件的 useEffect 里执行:
import * as React from 'react'; import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import raw from "./testfile.csv"; function readFile() { fetch(raw) .then(r => r.text()) .then(text => { console.log('text decoded:', text); }); } export default function App() { // 只在组件挂载时执行一次 React.useEffect(() => { readFile(); }, []); return ( <Container maxWidth="sm"> <Box sx={{ my: 4 }}> <Typography variant="h4" component="h1" gutterBottom> Create React App example </Typography> </Box> </Container> ); }
方案2:把 ReadFile 改成合法的 React 组件
如果要把它做成组件,需要让它返回 JSX(哪怕是空的),并把请求逻辑放到 useEffect 里:
import * as React from 'react'; import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import raw from "./testfile.csv"; function ReadFile() { React.useEffect(() => { fetch(raw) .then(r => r.text()) .then(text => { console.log('text decoded:', text); }); }, []); // 组件必须返回JSX,这里返回空片段 return null; } export default function App() { return ( <Container maxWidth="sm"> <Box sx={{ my: 4 }}> <Typography variant="h4" component="h1" gutterBottom> Create React App example </Typography> <ReadFile /> </Box> </Container> ); }
这样修改后,不管是开发还是生产环境,请求都会只执行一次。
内容的提问来源于stack exchange,提问作者cablesky
相关产品推荐
相关产品推荐

