使用 yarn 工作区和 react-router-dom v6 时如何正确继承上下文?
Posted
技术标签:
【中文标题】使用 yarn 工作区和 react-router-dom v6 时如何正确继承上下文?【英文标题】:How to inherit context correctly when using yarn workspaces and react-router-dom v6? 【发布时间】:2022-01-18 18:40:12 【问题描述】:我有一个使用 yarn 工作区和 lerna 的 monorepo。我的应用程序的结构基本上是一个用于导入其他纱线包的“中心”,我想做的是允许每个正在导入的包定义自己的Routes
。如果组件是从同一个包中导入的,这可以正常工作,但是当它们从其他 yarn 包中导入时,react router 上下文会丢失。
我认为问题在于这两个包都是导入的 react-router 的单独实例,因此 Router
的上下文没有从父组件传递到子组件。似乎similar to this issue with React context,但我不确定是否有解决方法或其他建议的方法来解决这个问题与反应路由器 v6。
我想要实现的一个简化示例是:
// ImportedApp.js
function ImportedApp()
return (
<Routes>
<Route path="/" element=<div>Root of app</div> />
<Route path="testSubSection" element=<div>Sub page of app</div> />
</Routes >
);
// App.js
import ImportedApp from 'ImportedApp';
function AppRoutes()
return (
<Routes>
<Route
path="/importedApp/*"
element=
<ImportedApp />
<Route
path="/"
element=<div>My App</div>
/>
</Routes>
);
在上面的例子中,如果 ImportedApp.js 与 App.js 在同一个包中,则没有问题。但是如果我有完全相同的代码并从单独的纱线包中导入它,我会得到
Uncaught Error: useRoutes() may be used only in the context of a <Router> component.
我尝试在我的package.json
中结合使用alias
和nohoist
,但到目前为止,没有什么能帮助我实现让两者共享相同库引用的目标。
【问题讨论】:
【参考方案1】:这里的修复是两折-
首先,需要添加react-router
和react-router-dom
的别名。但诀窍是,需要将此别名添加到 父包和继承包中。
所以parent-package
webpack 文件最终看起来像:
resolve:
alias:
'react-router-dom': join(__dirname, '..', 'node_modules', 'react-router-dom', '/'),
'react-router': join(__dirname, '..', 'node_modules', 'react-router', '/'),
,
extensions: ['.ts', '.tsx', '.js', '.jsx', '.less', '.css'],
,
以及继承的包:
resolve:
alias:
'react-router-dom': join(
__dirname,
'..',
'..',
'parent-package',
'node_modules',
'react-router-dom',
'/',
),
'react-router': join(
__dirname,
'..',
'..',
'parent-package',
'node_modules',
'react-router',
'/',
),
,
,
【讨论】:
以上是关于使用 yarn 工作区和 react-router-dom v6 时如何正确继承上下文?的主要内容,如果未能解决你的问题,请参考以下文章
无法使 react-hot-loader 和 webpack-dev-server 与 react-router 一起工作
使用 Yarn 工作区/nohoist 时,如何控制 Yarn 为依赖项的 peerDependency 选择哪个版本?