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

在Monorepo中使用react-responsive触发Invalid-hook-call错误求助

解决Monorepo中使用react-responsive触发Invalid-hook-call错误的思路

首先,Invalid-hook-call错误虽然提示在你的函数式组件里,但通常不是组件本身的问题,而是钩子的执行上下文不对。结合你的Monorepo+React Native Web+styled-components的场景,我整理了几个最可能的解决方向:

1. 优先排查Monorepo中重复的React实例

这是Monorepo里钩子错误的头号元凶:如果你的UI库和React Native应用各自安装了独立的React包,就会出现两个不同的React上下文,导致react-responsive内部的钩子无法识别当前组件的React环境。

解决步骤:

  • 在UI库的package.json中,把react、react-dom(如果用到)和react-native-web设为peerDependencies,而不是dependencies,确保UI库复用应用提供的React实例:
    "peerDependencies": {
      "react": "^17.0.0 || ^18.0.0",
      "react-dom": "^17.0.0 || ^18.0.0",
      "react-native-web": "^0.18.0"
    }
    
  • 在Monorepo根目录的package.json中,用包管理器的统一版本锁定功能强制所有工作区使用相同的React版本:
    • 若用yarn:添加resolutions字段
      "resolutions": {
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
      }
      
    • 若用pnpm:添加pnpm.overrides字段
      "pnpm": {
        "overrides": {
          "react": "^18.2.0",
          "react-dom": "^18.2.0"
        }
      }
      
  • 删除所有工作区的node_modules和锁文件,重新安装依赖。

2. 替换react-responsive为更适配React Native Web的方案

react-responsive本质是为Web环境设计的,在React Native Web中可能存在环境适配问题(比如依赖浏览器的window对象,或钩子逻辑和RNW渲染流程冲突)。你可以改用styled-components原生的媒体查询能力,完全能实现相同需求,还能避免额外的钩子依赖:

修改你的Card组件,去掉react-responsive,直接在样式里写媒体查询:

import styled from 'styled-components/native';
import { theme } from '@components/theme';

interface CardProps {
  children: React.ReactNode;
  tag: string;
}

const Card = (props: CardProps) => {
  console.log("Card -> props", props)
  return (
    <Container>
      <TagContainer>
        <Tag>{props.tag}</Tag>
        {/* 仅在桌面端显示的标签 */}
        <DesktopTag>'blablabla</DesktopTag>
      </TagContainer>
      <MainContent>{props.children}</MainContent>
    </Container>
  );
}

// 新增桌面端专属标签样式
const DesktopTag = styled.Text`
  display: none;
  @media (min-width: 1000px) {
    display: block;
    /* 这里添加桌面端标签的样式 */
  }
`;

// 其他样式保持不变
const Container = styled.View`
  display: flex;
  flexDirection: column;
  minWidth: ${theme.width.minCard};
  maxWidth: ${theme.width.maxCard};
  height: ${theme.height.card};
  boxShadow: 0 0 10px ${theme.colors.primaryGrey};
  border: 1px solid ${theme.colors.primaryYellow};
  borderRadius: ${theme.borderRadius.rectangular};
  marginBottom: ${theme.margins.medium};
`;

const TagContainer = styled.View`
  display: flex;
  flexDirection: row-reverse;
`;

这种方式完全利用styled-components的特性,和React Native Web的兼容性更好,也不会引入额外的钩子依赖。

3. 验证react-responsive的版本兼容性

如果一定要保留react-responsive,检查它的版本是否和你使用的React版本匹配:

  • React 18需要react-responsive >= 9.0.0版本
  • 如果你的React版本是17,确保react-responsive在8.x.x范围内

可以在UI库的package.json中明确指定兼容的版本,然后重新安装依赖。

4. 检查组件导出/导入的正确性

虽然可能性较低,但还是要确认UI库中的Card组件是正确导出为函数式组件,应用中是通过JSX语法调用(而不是当作普通函数执行)。比如UI库的导出是否是:

export default Card;
// 或者
export const Card = (props: CardProps) => { ... }

应用中的导入是否对应正确的导出方式。

内容的提问来源于stack exchange,提问作者E.D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:37:44