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

Next.js自定义Hook中访问Redux Toolkit Dispatch报错求助

问题:Next.js自定义Hook中使用Redux dispatch报错

我在Next.js应用中实现了一个用于生成Axios实例的自定义Hook,想在其中使用dispatch,但碰到了如下错误:

Error: could not find react-redux context value; please ensure the component is wrapped in a Provider

Hook代码如下:

import axios from 'axios';
import { useRouter } from 'next/router'
import { useAppDispatch } from '../store/hooks'
import { stopLoading } from '../store/features/loadingSlice'

const useAxiosInstance = () => {
    const dispatch = useAppDispatch()

    const router = useRouter()

    const instance = axios.create({
        baseURL: 'http://localhost:4000'
    });

    instance.defaults.withCredentials = true
    instance.interceptors.response.use((response) => {
        return response
    }, (error) => {
        if(error.response.status === 401 && window.location.href !== 'http://localhost:3000/') {
            router.push('/')
            dispatch(stopLoading())
        }
        return Promise.reject(error)
    })

    return instance
}

export default useAxiosInstance

解决方案

1. 确保应用被Redux Provider全局包裹

Redux的useDispatch(包括你自定义的useAppDispatch)依赖React Context,必须让整个应用组件树处于Provider的包裹下。在Next.js中,通常在_app.js/_app.tsx中配置:

import { Provider } from 'react-redux'
import { store } from '../store' // 你的Redux store实例
import '../styles/globals.css'

function MyApp({ Component, pageProps }) {
  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  )
}

export default MyApp

2. 仅在合法React上下文调用自定义Hook

useAxiosInstance作为自定义Hook,只能在React函数组件内部或者其他自定义Hook中调用,不能在普通函数、类组件,或者组件渲染流程之外的场景使用——这些环境无法访问Redux的Context。

3. 检查useAppDispatch的定义正确性

确保store/hooks.js中正确封装了useDispatch(TypeScript环境需保证类型正确,JS环境可省略类型):

import { useDispatch, useSelector } from 'react-redux'
import type { AppDispatch, RootState } from './index'

export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector = (selector) => useSelector<RootState>(selector)

额外优化:缓存Axios实例避免重复创建

当前代码每次调用useAxiosInstance都会生成新的Axios实例,存在性能浪费。可以用useMemo缓存实例,仅在依赖变化时重新创建:

import { useMemo } from 'react';
// ...其他导入

const useAxiosInstance = () => {
    const dispatch = useAppDispatch()
    const router = useRouter()

    const instance = useMemo(() => {
        const axiosInstance = axios.create({
            baseURL: 'http://localhost:4000'
        });

        axiosInstance.defaults.withCredentials = true
        axiosInstance.interceptors.response.use((response) => {
            return response
        }, (error) => {
            if(error.response?.status === 401 && window.location.href !== 'http://localhost:3000/') {
                router.push('/')
                dispatch(stopLoading())
            }
            return Promise.reject(error)
        })

        return axiosInstance
    }, [dispatch, router])

    return instance
}

export default useAxiosInstance

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:45:41