升级后无法让反应路由器工作
Posted
技术标签:
【中文标题】升级后无法让反应路由器工作【英文标题】:Cannot get react-router to work after upgrade 【发布时间】:2017-08-04 06:05:51 【问题描述】:我一直致力于将我们的应用程序从 React.js 0.13 升级到 15.4.2 以及围绕它的依赖项。我可能已经接近了,但在 4 天 50 小时后,我终于走到了尽头,我最后的希望。
在升级中,react-router 升级到版本 4.0.0,每个文档和教程以及堆栈溢出问题都显示了如何编写路由器(都一样,所以必须是正确的)但是,当我这样做时它总是失败。要么说历史是必需的属性,要么当我通过示例添加它时,它仍然显示为未定义和错误。
这是我们的 index.js 和路由器。
任何人都可以看到我没有正确理解的地方吗?谢谢
从“反应”导入反应;
// material ui
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Theme from './styles/theme.js';
import Header from './components/header.jsx';
import Home from './views/home.jsx';
import CaseController from 'controllers/caseController';
import LoginController from 'controllers/loginController';
import XController from 'controllers/xController';
import PredefinedSearchAssetCasesController from 'controllers/predefinedSearchAssetCasesController';
import PredefinedSearchCaseLabelsController from 'controllers/predefinedSearchCaseLabelsController';
import DeepSearchController from 'controllers/deepSearchController';
import NamesAndAddressController from 'controllers/namesAndAddressController';
import AccountListing from 'controllers/accountListingController';
import LoginStore from 'stores/loginStore';
import LoginActions from 'actions/loginActions';
import UtcStore from 'stores/utcStore';
import UtcActions from 'actions/utcActions';
import ErrorHandler from 'components/errorHandler';
import DialogMessageHandler from 'components/dialogMessageHandler';
import ConfirmationDialogHandler from 'components/confirmationDialogHandler';
// routing related
import render from 'react-dom';
import Router, Route, DefaultRoute, Link, hashHistory, browserHistory from 'react-router';
import versionNumber from 'raw-loader!../.version';
var App = React.createClass (
childContextTypes:
muiTheme: React.PropTypes.object
,
getChildContext()
return
muiTheme: MuiThemeProvider.get()
;
,
componentWillMount()
//ThemeManager.setTheme(Theme);
// TODO: consolidate into one request using /utc endpoint
if (_.isEmpty(UtcStore.claimUtcList))
UtcActions.getClaimUtcList();
if (_.isEmpty(UtcStore.assetUtcList))
UtcActions.getAssetUtcList();
if (_.isEmpty(UtcStore.transferUtcList))
UtcActions.getTransfers();
,
componentDidMount()
LoginStore.addChangeListener(this.onLoginChange);
if (!LoginStore.getLoginData())
this.transitionTo('login');
return false;
else
LoginActions.checkToken();
,
onLoginChange()
if (!LoginStore.getLoginData())
this.transitionTo('login');
,
render()
console.log('VERSION: ', versionNumber);
const styles =
root:
background: '#EEEEEE',
paddingTop: 55 // see header.jsx menuHeight
;
console.log('APP', this.context.router.getCurrentPath());
let hideHeaderRoutes = ["/login"];
let header = true;
if (this.context.router.getCurrentPath().indexOf(hideHeaderRoutes) > -1)
header = false;
styles.root = undefined;
return (
<MuiThemeProvider muiTheme=Theme>
<div style=styles.root>
header ? <Header /> :
<ErrorHandler
ref="errorHandler"
/>
<DialogMessageHandler
ref="dialogMessageHandler"
/>
<ConfirmationDialogHandler
ref="confirmDialogHandler"
/>
</div>
</MuiThemeProvider>
);
);
render((
<Router history=browserHistory>
<Route component=App path="/">
<DefaultRoute component=Home/>
<Route path="home" component=Home />
<Route path="case" component=CaseController />
<Route path="case/:id/?:reverseToken?" component=CaseController /> /* reverseToken is optional path variable for going back to last state when we go to case screen*/
<Route path="login" component=LoginController />
<Route path="x" component=XController />
<Route path="x/?:xDate?/?:xFromTime?/?:xToTime?/?:id?" component=XController />
<Route path="namesAndAddress" component=NamesAndAddressController />
<Route path="reconciliation/?:reverseToken?" component=AccountListing />
<Route path="asset-cases/:predefinedQuery/:sortBy/?:reverseToken?" component=PredefinedSearchAssetCasesController />
<Route path="case-labels/:predefinedQuery/:sortBy/?:reverseToken?" component=PredefinedSearchCaseLabelsController />
<Route path="deep-search/:deepSearchQuery/:sortBy/openCasesOnly::openCasesOnly/assetCasesOnly::assetCasesOnly/searchType::searchType/?:reverseToken?" component=DeepSearchController />
</Route>
</Router>
), document.body);
【问题讨论】:
【参考方案1】:History 对象似乎不再是 react-router 的一部分。所以,你 import Router, Route, DefaultRoute, Link, hashHistory, browserHistory from 'react-router';
实际上并没有导入 hashHistory 或 browserHistory。
基于examples,获取历史对象的一种解决方案是安装history/createBrowserHistory
package。
import Router from 'react-router'
import createBrowserHistory from 'history/createBrowserHistory'
const history = createBrowserHistory()
<Router history=history>
<App/>
</Router>
【讨论】:
感谢詹姆斯的回答。我尝试过并从历史记录中得到错误,createBrowserHistory 指向 es.createBrowserHistory,其中有错误。而且看起来 react-router 也不再有不幸的是,这个问题的答案是没有答案,react-router 4.00 需要 react-router-config 来像在早期版本中那样做静态路由。所以问题中上面的所有代码都是没有意义的。
【讨论】:
你查看this example了吗?它没有提到额外的模块。 basic example 也与您上面的配置非常相似。在经历了这个转换过程一段时间后,我可以与你的挑战联系起来:)。万事如意! 感谢 HazardouS,在第一个示例中,他们没有设置路由器的强制历史属性。第二个示例是使用最新的 1 周旧版本 4.0.0,我了解到它无法进行静态路由,除非它使用他们的 Alpha 版本的 react-router-config,它没有文档,我被告知他们认为 API 也会发生变化,因为它是 Alpha。所以我确实需要将我的升级降级到 3.0 版。 文档将在一段时间内赶上。可以看看你的回购吗? 使用withRouter
hoc 在您需要的任何组件中注入上下文。
当你到达那里时,从 v3 迁移到 v4 应该会更容易。以上是关于升级后无法让反应路由器工作的主要内容,如果未能解决你的问题,请参考以下文章
登录页面后反应路由器 v6 不会切换到主页:警告:无法对未安装的组件执行 React 状态更新