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

React按钮触发searchSpell报request非函数错误解决方法

问题描述

我在开发自己的第一个React项目,想要实现点击按钮触发searchSpell函数的功能,但按钮点击后始终无法正常运行,控制台持续抛出如下错误:

Uncaught TypeError: axios_api_js__WEBPACK_IMPORTED_MODULE_1_.default.request is not a function

相关代码如下:

Header组件代码

const { searchSpell } = Hooker();
const [whatSpell, setWhatSpell] = useState()

function pesquisar () {
    if(!whatSpell){
        alert("escreva alguma coisa antes de pesquisar")
        return
    } else{
        return searchSpell(whatSpell)
    }
}

自定义Hook代码

import { SpellContext } from "../provider.js"
function Hooker (){
    const { spellState, searchSpell } = useContext(SpellContext)
    return { spellState, searchSpell }
}
export default Hooker

BaseInfo上下文组件代码

function BaseInfo({ children }){

    const [spellState, setSpellState] = useState({
        name: undefined,
        desc: undefined,
        higher_level: undefined,
        range: undefined,
        components: undefined,
        material: undefined,
        ritual: false,
        duration: undefined,
        concentration: false,
        casting_time: undefined,
        level: 0,
    });

    const searchSpell = (spellName) => {
        api.request(spellName).then(function(response) {
            setSpellState(prevState => ({
                ...prevState,
                name: response.data.name,
                desc: response.data.desc,
                higher_level: response.data.higher_level,
                range: response.data.range,
                components: response.data.components,
                material: response.data.material,
                ritual: response.data.ritual,
                duration: response.data.duration,
                concentration: response.data.concentration,
                casting_time: response.data.duration,
                level: response.data.duration,
            })
            )
        })

        console.log(spellState.duration)
    }

    const contextValue = {
        spellState,
        searchSpell: useCallback((spellName) => searchSpell(spellName), []),
    }

    return(
        <SpellContext.Provider value={contextValue}>
            {children}
        </SpellContext.Provider>
    )
}

export default BaseInfo
问题原因与修复方案

报错xxx.default.request is not a function的直接原因是你导入的api对象上不存在request方法,从报错的webpack模块路径判断,问题出在你封装axios的api.js文件的导出/封装逻辑上:

  • 先检查导入导出是否匹配:如果你在BaseInfo组件里用import api from 'xxx/api.js'的默认导入写法,那api.js里必须用export default导出创建好的axios实例,不能写成命名导出export const api = xxx,否则你拿到的default导出是undefined或者空对象,自然找不到request方法。
  • 再检查api封装逻辑:原生axios实例本身自带.request()方法,如果你自己封装api的时候覆盖了默认导出,只导出了一个自定义了get/post方法的普通对象,没有保留request方法,调用时就会报这个错。如果你的咒语查询是GET请求,完全可以直接用api.get(请求地址)的写法,不用强行调用request。

正确的axios实例导出参考:

// 对应你的api.js文件
import axios from 'axios'
const api = axios.create({
  baseURL: '你后端接口的基础地址'
})
export default api

修完api的问题,代码里还有几个会导致功能异常的bug,需要一并修改:

  • 状态赋值笔误:更新spellState的时候,casting_time和level两个字段你都错写成了response.data.duration,要对应接口返回的字段改对:
    casting_time: response.data.casting_time,
    level: response.data.level,
    
  • 异步逻辑打印错误:你在api.request()调用后立刻写了console.log(spellState.duration),这时候接口请求还没返回,state还没更新,打印出来的永远是初始值undefined,要查看返回结果直接在then回调里打response.data就行,要监听state更新就加useEffect监听spellState变化。
  • useCallback依赖错误:你给searchSpell包useCallback的时候依赖数组传了空数组,会一直缓存组件第一次渲染时的searchSpell方法,后续状态更新不会同步,依赖数组要加上searchSpell:
    searchSpell: useCallback((spellName) => searchSpell(spellName), [searchSpell]),
    
  • 检查hooks导入:所有用到useState/useContext/useCallback的文件,都要在顶部从react里导入这些方法,不然也会抛错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 08:54:20