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

Monorepo自定义Hook报错:未找到react-redux上下文需包裹<Provider>

问题原因

这个报错不是你真的没在应用外层包裹<Provider>,核心原因是Lerna搭建的Monorepo架构下出现了react-redux多实例共存问题:

  • 你存放Redux逻辑的独立子包,自己在node_modules里安装了一份单独的react-redux依赖,和主应用里引入的react-redux是完全独立的两个实例
  • 主应用里用的<Provider>是主应用依赖的react-redux导出的,注入的上下文只对这份实例的Hooks生效;但你子包里封装的useSignInEffect调用的useSelector是子包自己那份react-redux导出的,读的是另一份独立的上下文,自然拿不到注入的store值,就会抛出找不到context的错误。
    其他Redux功能正常是因为那些逻辑要么写在主应用里用的是主应用的react-redux实例,要么是直接调用store实例方法不依赖context,只有子包里导出的Hook用的是子包自己的react-redux,才会触发这个问题。
修复步骤
  1. 先确认多实例问题
    在项目根目录执行命令检查依赖重复情况:
npm ls react-redux

如果输出结果里Redux子包的路径下单独挂载了一份react-redux,就可以确定是该问题导致。

  1. 调整子包依赖配置
    打开Redux子包的package.json,把react、react-dom、react-redux这类要求全局单实例的依赖,从dependencies字段移动到peerDependencies,明确声明这些依赖由宿主应用提供,子包不单独打包安装:
{
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "react-redux": ">=7.0.0"
  }
}

如果子包本地开发、单元测试需要用到这些依赖,可以放到devDependencies里,不要放到生产依赖中。
顺便补全你自定义Hook里缺失的useEffect引入,这个问题会直接抛出引用错误,虽然不是本次context报错的诱因,但也需要修复:

import { useEffect } from 'react';
import { useSelector } from 'react-redux';
import type { EffectCallback } from 'react';
import type { RootState } from './your-store-type-path';

export const useSignInEffect = (effect: EffectCallback) => {
  const isSignedIn = useSelector((state: RootState) => state.auth.isSignedIn);

  useEffect(() => {
    if (isSignedIn) {
      return effect();
    }
  }, [isSignedIn]);
};
  1. 清理缓存重装依赖
    在根目录执行命令删除所有残留依赖和锁文件,重新安装:
rm -rf node_modules packages/*/node_modules package-lock.json yarn.lock pnpm-lock.yaml
npm install
  1. pnpm用户额外配置
    如果你用pnpm作为Monorepo的包管理工具,还可以在根目录的.npmrc文件中添加如下配置,强制单实例依赖提升,避免多实例问题复现:
public-hoist-pattern[]=react
public-hoist-pattern[]=react-dom
public-hoist-pattern[]=react-redux

操作完成后重启开发服务,自定义Hook就能正常读取Provider注入的上下文,报错会消失。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:24:18