跨包使用React Native组件时触发多类错误的排查求助
背景
基于Storybook开发集成NativeWind的React Native组件库,通过tsc编译,GitHub Action自动发布为GitHub包。在另一项目引入组件时触发一系列错误,具体信息如下:
组件示例代码
import React from 'react'; import { Text } from 'react-native'; export interface ComponentProps { children: React.ReactNode; bold?: boolean; } const MyComponent = ({ children, bold = false, }: ComponentProps) => { return ( <Text className={`${bold && 'font-bold'} text-gray-800`} > {children} </Text> ); }; export default MyComponent;
tsconfig.json配置
{ "compilerOptions": { "module": "commonjs", "lib": [ "es2017", "es7", "es6", "dom" ], "declaration": true, "jsx": "react", "rootDir": "src", "outDir": "./dist", "allowSyntheticDefaultImports": true, "noImplicitAny": true, "sourceMap": true, "preserveConstEnums": true, "allowJs": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "skipLibCheck": true, "esModuleInterop": true }, "types": ["react", "react-dom", "react-native"], "exclude": [ "dist", "node_modules", "src/**/*.stories.tsx" ], "include": [ "src/**/*", "app.d.ts" ], "compileOnSave": false }
GitHub Action Workflow配置
name: Node.js Package on: release: types: [created] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: yarn install --frozen-lockfile publish-gpr: needs: build runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 registry-url: https://npm.pkg.github.com/ scope: '@username' - run: yarn install --frozen-lockfile - run: yarn build - run: npm publish env: NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
报错信息
Warning: Invalid hook call.
TypeError: Cannot read properties of null (reading 'useState')Invariant Violation: No callback found with cbID 1379 and callID 689 for module
. Args: '[19] Invariant Violation: No callback found with cbID 1385 and callID 692 for module
. Args: '[20]' Invariant Violation: Failed to call into JavaScript module method JSTimers.callTimers(). Module has not been registered as callable. Bridgeless Mode: false. Registered callable JavaScript modules (n = 0): .
A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.ExceptionsManager.js:153 Invariant Violation: No callback found with cbID 1860 and callID 930 for module
. Args: '[true]'
排查线索
- 组件代码未违规使用Hook
- 组件库与目标项目均使用React v18,但存在小版本差异,
yarn why react显示两个版本共存
解决方案
1. 统一React/React Native依赖版本
多版本React共存是核心诱因,React要求整个应用只能存在单一实例,否则会导致Hook调用上下文混乱。
- 在组件库的
package.json中,将react、react-native标记为peerDependencies,而非直接依赖:
这样组件库会复用宿主项目的React实例,避免版本冲突。"peerDependencies": { "react": "^18.0.0", "react-native": "^0.70.0" }, "devDependencies": { "react": "^18.0.0", "react-native": "^0.70.0" } - 宿主项目执行
yarn dedupe或npm dedupe,强制合并重复依赖。
2. 调整tsconfig编译配置
当前tsconfig.json的lib包含dom(浏览器环境),但React Native不需要,且jsx模式设置为react,建议修改为React Native适配的配置:
{ "compilerOptions": { // 保留其他配置 "lib": ["es2017"], "jsx": "react-native" } }
错误的JSX编译模式可能导致代码运行时上下文不兼容。
3. 规范组件引入方式
确保编译后的dist目录代码没有打包进React/React Native依赖,同时在组件库的src/index.ts统一导出组件:
// src/index.ts export { default as MyComponent } from './MyComponent';
宿主项目通过入口文件引入,避免直接引用单个组件文件:
import { MyComponent } from '@username/package-name';
4. 验证NativeWind配置一致性
确保组件库与宿主项目的tailwind.config.js规则一致,且宿主项目已正确集成NativeWind的Babel插件,避免样式编译导致的运行时异常。
内容的提问来源于stack exchange,提问作者Kevin Bryan

