У меня есть монорепо с несколькими приложениями и библиотеками, которое работает очень хорошо (на основе пряжи). В последнее время я провел некоторый рефакторинг и определил общий компонент, который я хотел «перенести» в библиотеку «общего достояния». Это содержит компонент, который использует ReactRouter.Route
:
import React from 'react';
import { Route, useHistory } from 'react-router-dom';
export const AuthenticatedRoute = (props: Props): JSX.Element => {
const history = useHistory(); // Crashes here
... do auth stuff ...
useEffect(() => {
if (!authenticated) {
history.push(...);
}
}, []);
return (
<Route {...props}>
{props.children}
</Route>
);
}
Этот компонент работает как шарм, когда содержал мое приложение реакции. Однако при извлечении в библиотеку commons
во время выполнения происходит сбой со следующей ошибкой:
Uncaught TypeError: Cannot read property 'history' of undefined
at useHistory (index.js:5914)
at AuthenticatedRoute (index.js:9848)
at renderWithHooks (react-dom.development.js:16260)
at mountIndeterminateComponent (react-dom.development.js:18794)
at beginWork$1 (react-dom.development.js:20162)
at HTMLUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at beginWork$$1 (react-dom.development.js:25780)
at performUnitOfWork (react-dom.development.js:24695)
Я думаю, это как-то связано с тем, как библиотека / приложение ссылаются на библиотеку react-router-dom
.
commons / package. json:
{
"name": "commons",
"version": "1.0.0",
"main": "dist/index.js",
"private": true,
"dependencies": {
},
"peerDependencies": {
"react-router-dom": "^5.1.2"
}
}
app / package. json:
{
"name": "app",
"version": "1.0.0",
"private": true,
"dependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"commons": "1.0.0"
}
}
app / app.ts:
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
export const App = (): JSX.Element => {
return (
<Router>
<AuthenticatedRoute />
</Router>
);
};
Примечание. Если я прокомментирую useHistory
, то в <Route>
произойдет сбой, сказав, что он должен быть потомком <Router>
.
То, что я пытался:
- использовать
peerDependencies
, чтобы библиотека и приложение использовали один и тот же экземпляр реагирующего маршрутизатора - чистить и устанавливать пряжу несколько раз
- дикие комбинации
react-router
& react-router-dom
зависимостей