上下文“路由器”在“重定向”中被标记为必需,但其值为“未定义”

时间:2019-05-09 08:28:30

标签: reactjs react-router

依赖项:

react@16.8.4
react-dom@16.8.4
react-router@4.3.1
react-router-dom@4.3.1

我有两个项目。我们将它们称为项目A和项目B。项目A是项目B的依赖项,并且在代码中多次包含以下行:

if (this.state.redirectToOverview) {
    return <Redirect push to={'/path'}/>;
}

但是每次我想使用重定向重定向到另一个页面时,都会出现以下错误(仅当从项目A进行的重定向被称为项目B的依赖项时才会发生此错误):

checkPropTypes.js:20 Warning: Failed context type: The context `router` is marked as required in `Redirect`, but its value is `undefined`.
    in Redirect
    in Login (created by LoadableComponent)
    in LoadableComponent (created by Context.Consumer)
    in Route (created by App)
    in Switch (created by App)
    in Router (created by HashRouter)
    in HashRouter (created by App)
    in App
printWarning @ checkPropTypes.js:20
checkPropTypes @ checkPropTypes.js:82
getMaskedContext @ react-dom.development.js:9656
constructClassInstance @ react-dom.development.js:11351
updateClassComponent @ react-dom.development.js:14687
beginWork @ react-dom.development.js:15644
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
renderRoot @ react-dom.development.js:19435
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
requestWork @ react-dom.development.js:20097
scheduleWork @ react-dom.development.js:19911
enqueueSetState @ react-dom.development.js:11169
push../node_modules/applicationA-frontend/node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:335
(anonymous) @ Login.js:92
setTimeout (async)
authenticate @ ClientSideAuthManager.js:9
(anonymous) @ Login.js:91
Promise.then (async)
(anonymous) @ Login.js:89
(anonymous) @ Login.js:67
Promise.then (async)
then @ request-base.js:253
(anonymous) @ Login.js:64
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:270
executeDispatch @ react-dom.development.js:561
executeDispatchesInOrder @ react-dom.development.js:583
executeDispatchesAndRelease @ react-dom.development.js:680
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:688
forEachAccumulated @ react-dom.development.js:662
runEventsInBatch @ react-dom.development.js:816
runExtractedEventsInBatch @ react-dom.development.js:824
handleTopLevel @ react-dom.development.js:4826
batchedUpdates$1 @ react-dom.development.js:20439
batchedUpdates @ react-dom.development.js:2151
dispatchEvent @ react-dom.development.js:4905
(anonymous) @ react-dom.development.js:20490
unstable_runWithPriority @ scheduler.development.js:255
interactiveUpdates$1 @ react-dom.development.js:20489
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
browser.js:38 Uncaught Error: You should not use <Redirect> outside a <Router>
    at invariant (browser.js:38)
    at Redirect.componentWillMount (Redirect.js:35)
    at callComponentWillMount (react-dom.development.js:11421)
    at mountClassInstance (react-dom.development.js:11514)
    at updateClassComponent (react-dom.development.js:14688)
    at beginWork (react-dom.development.js:15644)
    at performUnitOfWork (react-dom.development.js:19312)
    at workLoop (react-dom.development.js:19352)
    at HTMLUnknownElement.callCallback (react-dom.development.js:149)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:199)
invariant @ browser.js:38
componentWillMount @ Redirect.js:35
callComponentWillMount @ react-dom.development.js:11421
mountClassInstance @ react-dom.development.js:11514
updateClassComponent @ react-dom.development.js:14688
beginWork @ react-dom.development.js:15644
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
replayUnitOfWork @ react-dom.development.js:18578
renderRoot @ react-dom.development.js:19468
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
requestWork @ react-dom.development.js:20097
scheduleWork @ react-dom.development.js:19911
enqueueSetState @ react-dom.development.js:11169
push../node_modules/applicationA-frontend/node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:335
(anonymous) @ Login.js:92
setTimeout (async)
authenticate @ ClientSideAuthManager.js:9
(anonymous) @ Login.js:91
Promise.then (async)
(anonymous) @ Login.js:89
(anonymous) @ Login.js:67
Promise.then (async)
then @ request-base.js:253
(anonymous) @ Login.js:64
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:270
executeDispatch @ react-dom.development.js:561
executeDispatchesInOrder @ react-dom.development.js:583
executeDispatchesAndRelease @ react-dom.development.js:680
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:688
forEachAccumulated @ react-dom.development.js:662
runEventsInBatch @ react-dom.development.js:816
runExtractedEventsInBatch @ react-dom.development.js:824
handleTopLevel @ react-dom.development.js:4826
batchedUpdates$1 @ react-dom.development.js:20439
batchedUpdates @ react-dom.development.js:2151
dispatchEvent @ react-dom.development.js:4905
(anonymous) @ react-dom.development.js:20490
unstable_runWithPriority @ scheduler.development.js:255
interactiveUpdates$1 @ react-dom.development.js:20489
interactiveUpdates @ react-dom.development.js:2170
dispatchInteractiveEvent @ react-dom.development.js:4882
react-dom.development.js:17117 The above error occurred in the <Redirect> component:
    in Redirect
    in Login (created by LoadableComponent)
    in LoadableComponent (created by Context.Consumer)
    in Route (created by App)
    in Switch (created by App)
    in Router (created by HashRouter)
    in HashRouter (created by App)
    in App

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://..../react-error-boundaries to learn more about error boundaries.

此消息甚至意味着什么?我根本不知道我在做什么错或在哪里看。

在某些情况下(例如登录)弹出的又一个非常类似的错误消息是:

Warning: Failed context type: The context `router` is marked as required in `Switch`, but its value is `undefined`.
    in Switch
    in Suspense
    in div
    in main
    in div
    in div
    in DefaultLayout (created by ApplicationLayout)
    in ApplicationLayout (created by LoadableComponent)
    in LoadableComponent (created by Context.Consumer)
    in Route (created by PrivateRoute)
    in PrivateRoute (created by App)
    in Switch (created by App)
    in Router (created by HashRouter)
    in HashRouter (created by App)
    in App
printWarning @ checkPropTypes.js:20
checkPropTypes @ checkPropTypes.js:82
getMaskedContext @ react-dom.development.js:9656
constructClassInstance @ react-dom.development.js:11351
updateClassComponent @ react-dom.development.js:14687
beginWork @ react-dom.development.js:15644
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
renderRoot @ react-dom.development.js:19435
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
requestWork @ react-dom.development.js:20097
scheduleWork @ react-dom.development.js:19911
enqueueSetState @ react-dom.development.js:11169
./node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:335
update @ index.js:205
(anonymous) @ index.js:215
Promise.then (async)
_loadModule @ index.js:214
componentWillMount @ index.js:168
callComponentWillMount @ react-dom.development.js:11421
mountClassInstance @ react-dom.development.js:11514
updateClassComponent @ react-dom.development.js:14688
beginWork @ react-dom.development.js:15644
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
renderRoot @ react-dom.development.js:19435
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
requestWork @ react-dom.development.js:20097
scheduleWork @ react-dom.development.js:19911
scheduleRootUpdate @ react-dom.development.js:20572
updateContainerAtExpirationTime @ react-dom.development.js:20600
updateContainer @ react-dom.development.js:20657
./node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:20953
(anonymous) @ react-dom.development.js:21090
unbatchedUpdates @ react-dom.development.js:20459
legacyRenderSubtreeIntoContainer @ react-dom.development.js:21086
render @ react-dom.development.js:21155
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:766
fn @ bootstrap:129
0 @ bundle.js:30584
__webpack_require__ @ bootstrap:766
(anonymous) @ bootstrap:901
(anonymous) @ bootstrap:901
browser.js:38 Uncaught Error: You should not use <Switch> outside a <Router>
    at invariant (browser.js:38)
    at Switch.componentWillMount (Switch.js:27)
    at callComponentWillMount (react-dom.development.js:11421)
    at mountClassInstance (react-dom.development.js:11514)
    at updateClassComponent (react-dom.development.js:14688)
    at beginWork (react-dom.development.js:15644)
    at performUnitOfWork (react-dom.development.js:19312)
    at workLoop (react-dom.development.js:19352)
    at HTMLUnknownElement.callCallback (react-dom.development.js:149)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:199)
invariant @ browser.js:38
componentWillMount @ Switch.js:27
callComponentWillMount @ react-dom.development.js:11421
mountClassInstance @ react-dom.development.js:11514
updateClassComponent @ react-dom.development.js:14688
beginWork @ react-dom.development.js:15644
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
replayUnitOfWork @ react-dom.development.js:18578
renderRoot @ react-dom.development.js:19468
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
requestWork @ react-dom.development.js:20097
scheduleWork @ react-dom.development.js:19911
enqueueSetState @ react-dom.development.js:11169
./node_modules/react/cjs/react.development.js.Component.setState @ react.development.js:335
update @ index.js:205
(anonymous) @ index.js:215
Promise.then (async)
_loadModule @ index.js:214
componentWillMount @ index.js:168
callComponentWillMount @ react-dom.development.js:11421
mountClassInstance @ react-dom.development.js:11514
updateClassComponent @ react-dom.development.js:14688
beginWork @ react-dom.development.js:15644
performUnitOfWork @ react-dom.development.js:19312
workLoop @ react-dom.development.js:19352
renderRoot @ react-dom.development.js:19435
performWorkOnRoot @ react-dom.development.js:20342
performWork @ react-dom.development.js:20254
performSyncWork @ react-dom.development.js:20228
requestWork @ react-dom.development.js:20097
scheduleWork @ react-dom.development.js:19911
scheduleRootUpdate @ react-dom.development.js:20572
updateContainerAtExpirationTime @ react-dom.development.js:20600
updateContainer @ react-dom.development.js:20657
./node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:20953
(anonymous) @ react-dom.development.js:21090
unbatchedUpdates @ react-dom.development.js:20459
legacyRenderSubtreeIntoContainer @ react-dom.development.js:21086
render @ react-dom.development.js:21155
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:766
fn @ bootstrap:129
0 @ bundle.js:30584
__webpack_require__ @ bootstrap:766
(anonymous) @ bootstrap:901
(anonymous) @ bootstrap:901
react-dom.development.js:17117 The above error occurred in the <Switch> component:
    in Switch
    in Suspense
    in div
    in main
    in div
    in div
    in DefaultLayout (created by ApplicationLayout)
    in ApplicationLayout (created by LoadableComponent)
    in LoadableComponent (created by Context.Consumer)
    in Route (created by PrivateRoute)
    in PrivateRoute (created by App)
    in Switch (created by App)
    in Router (created by HashRouter)
    in HashRouter (created by App)
    in App

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://..../react-error-boundaries to learn more about error boundaries.

我真的看不到重定向或交换机在路由器之外的情况。那似乎并不是真的。

编辑:

这也可能相关:

import React, { Component } from 'react';
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom';
import Loadable from 'react-loadable';
import './App.scss';

const loading = () => <div className="animated fadeIn pt-3 text-center"><div className="spinner"/></div>;

// Containers
const DefaultLayout = Loadable({
  loader: () => import('./containers/DefaultLayout'),
  loading
});

// Pages
const Login = Loadable({
  loader: () => import('./views/Pages/Login'),
  loading
});

const Activation = Loadable({
  loader: () => import('./views/Activation/Activation'),
  loading
});

const Register = Loadable({
  loader: () => import('./views/Pages/Register'),
  loading
});

const Page404 = Loadable({
  loader: () => import('./views/Pages/Page404'),
  loading
});

const Page500 = Loadable({
  loader: () => import('./views/Pages/Page500'),
  loading
});

class App extends Component {

  render() {

    function PrivateRoute ({component: Component, authed, ...rest}) {
      return (
        <Route {...rest} render={props => (
            localStorage.getItem('authStatus')
            ? <Component {...props} />
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
        )} />
      )
    }

    return (
      <HashRouter>
        <Switch>
          <Route exact path="/login" name="Login Page" component={Login} />
          <Route exact path="/activateprofile" name="Activate profile" component={Activation} />
          <Route exact path="/register" name="Register Page" component={Register} />
          <Route exact path="/404" name="Page 404" component={Page404} />
          <Route exact path="/500" name="Page 500" component={Page500} />
          <PrivateRoute path='/' component={DefaultLayout} />
        </Switch>
      </HashRouter>
    );
  }
}

export default App;

EDIT2:

在第二条错误消息中提到的DefaultLayout中:

<div>
    <Suspense fallback={this.loading()}>
      <Switch>
         {this.getRoutes().map((route, idx) => {
          return route.component && (this.state.rights.some(e => e.content === route.right) || !route.right ) ? (
            <Route
              key={idx}
              path={route.path}
              exact={route.exact}
              name={route.name}
              render={props => (
                <route.component {...props} />
              )} />
          ) : (null);
        })}
        <Redirect from="/" to="/home" />
     </Switch>
    </Suspense>
  </div>

在第一个堆栈跟踪中提到的Login组件中:

if (redirectToReferrer === true) {
    return <Redirect to={from}/>
}

1 个答案:

答案 0 :(得分:0)

问题在于,当我对此项目执行node_modules时,作为项目B依赖项的项目A具有一个npm link文件夹。当node_modules被删除/不存在时,所描述的问题不再发生。

编辑:

实际上,事实证明这不是真正的解决方案。适用于所有项目的解决方案是您必须手动添加与react-router相同版本的react-router-dom