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

React自定义Hook使用Axios时出现Cannot read properties of undefined错误

问题分析与解决

1. 核心错误:变量解构名称不匹配

你的自定义Hook useAxios 返回的对象属性是 response、error、loading,但组件里解构时错误写成了 playerResponse、playerError、playerLoading。这会导致 playerResponse 实际是 undefined,自然无法读取 result 属性,触发 Cannot read properties of undefined (reading 'result') 报错。

2. 次发问题:渲染流程中直接调用setState

即使解构名称正确,你在组件顶层直接写 if (response !== null ) { setPlayerData(response.result); } 会引发无限重渲染:每次调用 setPlayerData 触发组件重新渲染,渲染时又会执行该条件判断,再次调用 setState,形成死循环。

3. 自定义Hook的潜在问题

  • axios请求参数顺序错误:get请求的第二个参数是配置对象,而非单独的headers和body,当前写法会把headers当作data传递,不符合axios API规范。
  • headers默认值处理冗余:用JSON.stringify转成字符串再JSON.parse解析完全没必要,直接用对象即可。
  • baseURL设置冲突:同时配置axios.defaults.baseURL和自定义baseURL,可能导致请求地址混乱。

修正后的代码

自定义Hook:useAxios.js

import { useState, useEffect } from 'react';
import axios from 'axios';

// 统一设置baseURL,避免冲突
axios.defaults.baseURL = 'http://127.0.0.1:5000/v1/test_server/';

const useAxios = ({ url, method='get', data = null, headers = { accept: '*/*' } }) => {
    const [response, setResponse] = useState(null);
    const [error, setError] = useState('');
    const [loading, setLoading] = useState(true);

    const fetchData = async () => {
        try {
            const config = {
                method,
                url,
                headers,
                // 根据请求方法处理数据:get用params,post/put用data
                ...(method.toLowerCase() === 'get' ? { params: data } : { data })
            };
            const res = await axios(config);
            setResponse(res.data);
        } catch (err) {
            setError(err.message || '请求失败');
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchData();
    }, [method, url, data, headers]);

    return { response, error, loading };
};

export default useAxios;

组件使用示例

import { useState, useEffect } from 'react';
import useAxios from './useAxios';

const PlayerComponent = () => {
    const [playerData, setPlayerData] = useState();
    // 正确解构,用别名区分不同请求的返回值
    const { response: playerResponse, error: playerError, loading: playerLoading } = useAxios({ url: 'player/get_player' });

    // 用useEffect监听response变化,避免无限重渲染
    useEffect(() => {
        if (playerResponse) {
            setPlayerData(playerResponse.result);
            console.log("Response", playerResponse.result);
        }
    }, [playerResponse]);

    if (playerLoading) return <div>加载中...</div>;
    if (playerError) return <div>错误:{playerError}</div>;

    return (
        <div>
            {playerData && <div>玩家数据:{JSON.stringify(playerData)}</div>}
        </div>
    );
};

export default PlayerComponent;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:45:26