开发者问题收集

React Router onEnter 函数“未捕获的 RangeError:超出最大调用堆栈大小”

2017-01-26
599

我正在检查是否设置了配置值,如果是,我想重定向到子路由。如果不是,则像往常一样显示。代码确实按预期更新了 URL,但随后陷入了无限循环。

index.js

import React from 'react'
import { render } from 'react-dom'
import { Router, Route, browserHistory, IndexRoute } from 'react-router'
import App from './modules/App'
import About from './modules/About'
import Map from './modules/Map'
import Maps from './modules/Maps'
import Home from './modules/Home'
import { settings } from './appconfig.js';

function checkDefaultFloor(){
  if (settings.floorUrl){
    console.log( settings.floorUrl);
     browserHistory.push('/maps/'+ settings.floorUrl);
  }
}

render((
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Home}/>
      <Route path="/maps" component={Maps}  onEnter={checkDefaultFloor}>
        <Route path="/maps/:mapName" component={Map}/>
      </Route>
      <Route path="/about" component={About}/>
    </Route>
  </Router>
), document.getElementById('app'))

在此处输入图片说明

3个回答

我遇到了类似的问题。解决方案是实施 Shubham Khatri 建议的方法。但是,我最初忽略的一个重要点是将 onEnter 回调附加到 IndexRoute。我使用标准 JavaScript 对象来定义我的路由。这是我需要做的:

{
  path: '/',
  indexRoute: {
    onEnter: (nextState, replace) => replace('some-route')
  },
  childRoutes: [...]
}

我敢打赌,OP 的 JSX 代码也存在类似的问题。它可能应该是这样的(虽然我没有测试过):

function checkDefaultFloor(nextState, replace, callback){
  if (settings.floorUrl){
    console.log( settings.floorUrl);
    replace(`/maps/${settings.floorUrl}`)
  }
  callback();
}
<Router history={browserHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Home}/>
      <Route path="/maps" component={Maps}>
        <IndexRoute onEnter={checkDefaultFloor}/>
        <Route path="/maps/:mapName" component={Map}/>
      </Route>
      <Route path="/about" component={About}/>
    </Route>
  </Router>
Bryan Downing
2017-04-03

它会进入无限循环,因为每次您输入路线 /maps 时,都会执行 checkDefaultFloor() ,重定向到 /map 的子级之一。

重定向会再次触发 onEnter -> checkDefaultFloor() ,因此无限递归。

您需要做的是移动 <Maps />componentDidMount 中的功能,或者检查您是否尚未重定向,例如

hasRedirected = false;

function checkDefaultFloor(){
  if (settings.floorUrl && !hasRedirected) {
    hasRedirected = true;
    browserHistory.push('/maps/'+ settings.floorUrl);
  }
}
Lyubomir
2017-01-26

由于路由嵌套在 map 路由内,因此 browserHistory.push() 语句使其陷入无限循环。您需要使用 replace 函数和 callback 等。

function checkDefaultFloor(nextState, replace, callback){
  if (settings.floorUrl){
    console.log( settings.floorUrl);
     replace(`/maps/${settings.floorUrl}`)
  }
  callback();
}
Shubham Khatri
2017-01-26