使用useSWR点击触发请求遇两类错误:Hook合规性及渲染报错求助
问题修复方案
错误1:useSWR调用位置不符合Hook规则
原因
React Hooks(包括useSWR)必须在React函数组件的顶层或自定义Hook的顶层调用,不能放在普通函数(比如你提到的fetchUsers)、条件判断、循环或嵌套函数里。你的代码里useSWR被放在了非组件/非Hook的函数中,违反了Hook规则。
修复
将useState和useSWR移到React函数组件的顶层,确保它们在组件渲染时直接执行,而非嵌套在其他函数内。示例代码如下:
import { useState } from 'react'; import useSWR from 'swr'; import axios from 'axios'; import { Box, Button, Typography } from '@mui/material'; // React函数组件 function UserPortal() { // Hooks必须放在组件顶层 const [shouldFetch, setShouldFetch] = useState(false); const fetcher = (url) => axios.get(url).then((res) => res.data); // 通过shouldFetch控制请求触发,符合Hook规则 const { data, error, isLoading } = useSWR(shouldFetch ? "http://localhost:5000/users" : null, fetcher); // 点击事件处理函数 const handleFetch = () => { setShouldFetch(true); }; return ( <div> <Box> <Button onClick={handleFetch}>View User</Button> </Box> {/* 修正后的渲染逻辑 */} <Typography> {!shouldFetch ? 'Students Portal' : ( isLoading ? 'Loading...' : ( error ? 'Failed to load users' : ( <div> {data.name.map(user => ( <div key={user.id}> ID: {user.id}, Age: {user.age} </div> ))} </div> ) ) )} </Typography> </div> ); } export default UserPortal;
错误2:Cannot read properties of undefined (reading 'name')
原因
- 当
shouldFetch变为true后,SWR发起请求但数据尚未返回时,data处于undefined状态,直接访问data.name会触发报错。 - 按钮点击事件语法错误:
onClick= setShouldFetch(true)会在组件渲染时立即执行状态变更,而非点击时触发,导致页面初始化就尝试访问未加载的data。
修复
- 修正按钮点击事件:将
onClick= setShouldFetch(true)改为onClick={() => setShouldFetch(true)},确保仅在点击时触发状态更新。 - 处理请求状态:
- 用SWR返回的
isLoading判断是否处于加载状态,显示加载提示。 - 用
error判断请求是否失败,显示错误信息。 - 必须先判断
data是否存在,再访问其属性(或使用可选链data?.name),避免访问undefined的属性。 - 接口返回的
name是数组,需遍历渲染每个用户的具体信息,而非直接渲染数组本身。
- 用SWR返回的
若需要每次点击都重新发起请求,可将shouldFetch替换为时间戳变量,确保每次点击都生成新的请求key:
const [fetchKey, setFetchKey] = useState(null); const handleFetch = () => { setFetchKey(Date.now()); }; const { data, error, isLoading } = useSWR(fetchKey ? "http://localhost:5000/users" : null, fetcher);
内容的提问来源于stack exchange,提问作者Tini
相关产品推荐
相关产品推荐

