admin管理员组文章数量:1312639
I have a shared (React) ponent library that I'm building. There is a PrivateRoute
ponent that I am wanting to include. However, when I import the ponent from the module library into another application, I get an error:
Error: Invariant failed: You should not use <Redirect> outside a <Router>
The PrivateRoute
ponent wraps the react-router/Route
ponent with authentication logic and redirects unauthenticated requests to login:
ponent-library
import { Route, Redirect } from 'react-router';
/* ... */
class PrivateRoute extends Component {
/* ... */
render() {
const {
ponent: Comp, authState, loginPath, ...rest
} = this.props;
return (
<Route
{...rest}
render={props => authState === SIGNED_IN ? (
<Comp {...props} />
) : (
<Redirect
to={{
pathname: loginPath,
}}
/>
)}
/>
);
}
}
I then import the ponent into a separate (React) project:
create-react-app
import { Router } from 'react-router';
import { PrivateRoute } from 'ponent-library';
/* ... */
class App extends Component {
// "history" is passed in via props from the micro frontend controller.
/* ... */
render() {
return (
<Router history={this.props.history}>
{/* ... */}
<PrivateRoute path="/protected" ponent={ProtectedView} />
</Router>
);
}
}
This will work as expected if the PrivateRoute
ponent is defined in the create-react-app application. However, moving this ponent to the shared library results in the error.
I have tried building the library with webpack output libraryTarget
set to monjs2. But, I've also tried umd. I've also tried with Rollup. All with the same results.
webpack.config.js
module.exports = {
//...
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '',
filename: '[name].js',
libraryTarget: 'monjs2',
},
//...
};
My assumption is that the issue is with building the ponent library as the Invariant error is thrown when Redirect
is unable to find the RouterContext
. Although the library builds without errors, it seems that importing piled/built code is a problem.
Could also be two instances of React causing an issue with the Context API. However, react-router
is not using the Context API. It's using the mini-create-react-context
polyfill.
Any thoughts or ideas on how to resolve this?
I have a shared (React) ponent library that I'm building. There is a PrivateRoute
ponent that I am wanting to include. However, when I import the ponent from the module library into another application, I get an error:
Error: Invariant failed: You should not use <Redirect> outside a <Router>
The PrivateRoute
ponent wraps the react-router/Route
ponent with authentication logic and redirects unauthenticated requests to login:
ponent-library
import { Route, Redirect } from 'react-router';
/* ... */
class PrivateRoute extends Component {
/* ... */
render() {
const {
ponent: Comp, authState, loginPath, ...rest
} = this.props;
return (
<Route
{...rest}
render={props => authState === SIGNED_IN ? (
<Comp {...props} />
) : (
<Redirect
to={{
pathname: loginPath,
}}
/>
)}
/>
);
}
}
I then import the ponent into a separate (React) project:
create-react-app
import { Router } from 'react-router';
import { PrivateRoute } from 'ponent-library';
/* ... */
class App extends Component {
// "history" is passed in via props from the micro frontend controller.
/* ... */
render() {
return (
<Router history={this.props.history}>
{/* ... */}
<PrivateRoute path="/protected" ponent={ProtectedView} />
</Router>
);
}
}
This will work as expected if the PrivateRoute
ponent is defined in the create-react-app application. However, moving this ponent to the shared library results in the error.
I have tried building the library with webpack output libraryTarget
set to monjs2. But, I've also tried umd. I've also tried with Rollup. All with the same results.
webpack.config.js
module.exports = {
//...
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '',
filename: '[name].js',
libraryTarget: 'monjs2',
},
//...
};
My assumption is that the issue is with building the ponent library as the Invariant error is thrown when Redirect
is unable to find the RouterContext
. Although the library builds without errors, it seems that importing piled/built code is a problem.
Could also be two instances of React causing an issue with the Context API. However, react-router
is not using the Context API. It's using the mini-create-react-context
polyfill.
Any thoughts or ideas on how to resolve this?
Share Improve this question edited Jun 24, 2019 at 15:39 Corey asked Jun 21, 2019 at 17:39 CoreyCorey 5,8182 gold badges25 silver badges37 bronze badges 3- Where you are importing Router from ? – Mosè Raguzzini Commented Jun 24, 2019 at 14:42
- Importing Router from 'react-router'. 'react-router' is a production dependency in the ponent library. So, the 'create-react-app' does not list 'react-router' as a dependency, but imports the Router from 'react-router' and PrivateRoute from the ponent library. – Corey Commented Jun 24, 2019 at 14:58
- Is there a way to get a sandbox that reproduces this? I've tried at codesandbox.io/s/a-simple-react-router-v4tutorial-stnxs but I can't manage to – apokryfos Commented Jun 24, 2019 at 16:22
4 Answers
Reset to default 3 +50You have to import router (assuming you're using V4) from react-router-dom, eg:
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
In v4, react-router exports the core ponents and functions. react-router-dom exports DOM-aware ponents, like <Link> (which renders an <a>) and <BrowserRouter> (which interacts with the browser's window.history ).
react-router-dom re-exports all of react-router's exports, so you only need to import from react-router-dom in your project.
Ref: https://github./ReactTraining/react-router/issues/4648#issuement-284479720
I did finally discover the issue which had little to do with react-router
and more with React
. I found that this error would only show in local development because the ponent-library
was linked via npm link
.
The resolution came from this answer: https://stackoverflow./a/38818358/715597
The solution in my case was to link React and React Router in the ponent library to the applications reference of React and React Router:
# link the ponent library
cd my-app
npm link ../ponent-library
# link its copy of React back to the app's React
cd ../ponent-library
npm link ../my-app/node_modules/react
npm link ../my-app/node_modules/react-router
Can't you do it using a function
if(authState === SIGNED_IN){
return <Route
{...rest}
render={<Comp {...props} />
/>
}else{
// here you can use window.location
// or
// render a different ponent (which shows unauthorized or something you want)
}
you only needed to remove dependency "react-router-dom": "5.0.0" from package.json to fix the error.
本文标签: javascriptExport reactrouter Redirect from shared component libraryStack Overflow
版权声明:本文标题:javascript - Export `react-router` Redirect from shared component library - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741916610a2404771.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论