使用 React Router 时无法访问 App 组件
Posted
技术标签:
【中文标题】使用 React Router 时无法访问 App 组件【英文标题】:Unable to access App component when using React Router 【发布时间】:2020-02-05 06:57:50 【问题描述】:我正在尝试使我的应用程序更受路线驱动/控制。我正在使用React Router
和一个外部路由文件,以便从我的组件中抽象出路由逻辑。除 App 组件本身外,其他路由和组件均正常工作。我实际上是在尝试将所有其他路由包装在根路由('/'
)下,其组件是App.js
。
下面是我的routes/index.js
文件。
import React from "react";
import PropTypes from "prop-types";
import Router, Route, Redirect from "react-router";
import App from "../App.js";
import Home from "../components/Home/Home";
import Games from "../components/Games/containers/Games";
import LoginSignUp from "../components/LoginSignUp/LoginSignUp";
import NotFound from "../components/NotFound/NotFound";
import Account from "../components/Account/Account";
import Trivia from "../components/Trivia/Trivia";
import store from '../config/store';
const getGame = (nextState, replace, callback) =>
var userGames = store.getState().auth.user.games;
if (userGames.includes(parseInt(nextState.match.params.id)))
return <Trivia/>
else
return <Redirect to="/404"/>
;
const Routes = ( history, store ) =>
return (
<Router history=history store=store>
<Route path="/" component=App>
<Route exact path="/404" component=NotFound />
<Route exact path="/give/different/path" component=Home/>
<Route exact path="/games" component=Games/>
<Route path="/account" component=Account/>
<Route path="/games/:id" render=getGame/>
<Route path='/login' component=LoginSignUp/>
</Route>
</Router>
);
;
Routes.propTypes =
history: PropTypes.object.isRequired,
store: PropTypes.object.isRequired
;
export default Routes;
我也试过这个没有<Route exact path="/" component=Home/>
的路由设置,我试过使用<Route exact path="/" component=App>
无济于事。
下面是我的App.js
组件。
import React from 'react';
import Header from './components/Header/Header.js';
import './App.css';
import createAction from "redux-actions";
import connect from "react-redux";
class App extends React.Component
state =
loggedIn: true
render()
debugger
return (
<div className="App">
<Header loggedIn=this.state.loggedIn user=this.props.user/>
</div>
);
const mapStateToProps = (games, auth) =>
return
user: auth.user,
games: games.games
;
const mapDispatchToProps = dispatch =>
return
getGame(obj)
const actionCreator = createAction(
"games/getGame"
);
const action = actionCreator(obj);
dispatch(action);
;
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
这是我的相关依赖项及其版本。
"react-router": "^5.1.2",
"react-router-dom": "^5.1.0",
"react-router-redux": "^4.0.8",
【问题讨论】:
【参考方案1】:它不会那样工作,看看你有一个路径/
对应App
然后/
对应Home
,它无法正确匹配。请查看 React Router 文档。这是nested routes 示例的链接。
为了让你去某个地方看看这个对你的路由器的修改 你有:
<Route path="/" component=App>
<Route exact path="/404" component=NotFound />
<Route exact path="/" component=Home/>
<Route exact path="/games" component=Games/>
<Route path="/account" component=Account/>
<Route path="/games/:id" render=getGame/>
<Route path='/login' component=LoginSignUp/>
</Route>
但效果会更好
<Route exact path="/" component=App />
<Route exact path="/home" component=Home/>
<Route exact path="/account" component=Account/>
<Route exact path="/games" component=Games/>
<Route exact path="/games/:id" render=getGame/>
<Route exact path='/login' component=LoginSignUp/>
<Route component=NotFound />
【讨论】:
感谢您的回复。我可以点击 App 组件,但我收到一条错误消息You should not use <Link> outside a <Router>
,我假设它来自我的导航组件,它位于 App.js
中,但由于 App
本身被包裹在 <Router>
中,它不会感觉它的子组件(以及任何后续链接)也将被包裹在 <Router>
?
应该,如果您查看链接,您会发现确实如此。看起来它是在文档中完成的。
我查看了链接,它很有帮助。从技术上讲,我的<Link/>
位于<Header/>
组件中,但仅在<App/>
中导入,其他任何地方都没有。就像<App/>
在<Header/>
之前被点击。除非<Link/>
必须在<App/>
中,而不是<App/>
的孩子。
有什么方法可以使用路由将其他组件包装在<App/>
中?我希望<App/>
中的<Header/>
出现在所有页面上,我可以通过使App
的路径包含(不是确切路径)来做到这一点,但这会产生一个问题,即URL 可以是/not-valid-url
然后它将呈现<Header/>
和一个空白页。【参考方案2】:
我认为您应该以这种方式更改您的代码。 并在导入时检查应用组件的路径
<Router history=history store=store>
<Switch>
<Route path="/" component=App />
<Route exact path="/404" component=NotFound />
<Route exact path="/home" component=Home />
<Route exact path="/games" component=Games />
<Route path="/account" component=Account />
<Route path="/games/:id" render=getGame />
<Route path="/login" component=LoginSignUp />
</Switch>
</Router>;
【讨论】:
感谢您的回复。我尝试过这种方式,但我得到一个错误,说You should not use <Link> outside a <Router>
我假设它来自我的导航组件,它位于 App.js
但由于 App
本身被包裹在 <Router>
组件(以及任何后续链接)也将包含在 <Router>
?另外,将exact path
用于Home
和path
用于App
有什么意义?
***.com/questions/49162311/…检查一下
是的,如果您的 <Link/>
在应用程序组件中,那么它应该可以工作
从技术上讲,它在 <Header/>
组件中,但仅在 <App/>
中导入,其他任何地方都没有。就像<App/>
在<Header/>
之前被点击。除非 <Link/>
必须在 <App/>
中,而不是 <App/>
的子级。
开关不维护App
与子组件,它似乎只显示App
。当我取下开关时,效果更好。【参考方案3】:
借助其他答案提供的见解,我能够想出一个解决方案来满足我的所有需求。
这是我更新的文件。第一个是我的根index
文件。作为预防措施,我用this issue's answer 建议的import BrowserRouter as Router from 'react-router-dom'
替换了所有import Router from 'react-router'
实例。将所有react-router
实例替换为react-router-dom
有助于阻止You should not use <Switch> outside a <Router>
或You should not use <Route> outside a <Router>
错误。
<Provider store=store>
<Router history=browserHistory store=store>
<App/>
</Router>
</Provider>
我的路线/索引。
const Routes = ( history, store ) =>
return (
<Switch>
<Route exact path="/" component=Home />
<Route exact path="/404" component=NotFound />
<Route exact path="/games" component=Games />
<Route exact path="/account" render=accountDetails/>
<Route path="/games/:id" render=getGame />
<Route exact path="/login" component=LoginSignUp />
<Redirect to='404' />
</Switch>
);
;
App 现在包括以下内容。
import Routes from './routes/index.js';
class App extends React.Component
state =
loggedIn: true
;
render()
return (
<div className="App">
<Header/>
<Routes/>
</div>
);
首先,我决定从routes/index
中删除App
。我的原始路由层次结构基于另一个未使用react-router 4
的项目。这就是为什么在另一个项目中,App
路由下的嵌套路由实现了我想要的。在react router 4
this was not possible 中,因此出现Cannot use Link outside of Router
错误。因此,我将App
包装在我的根索引文件中的Router
中,然后将所有其他路由包装在我的routes/index
文件中的Switch
中,并将它们导入App
。 App
现在可以将路由器用于Header
组件以及包裹在Switch
中的其他路由。
这也解决了我不得不为App
牺牲exact path
的问题。因为我想在每一页上使用Header
,所以我希望App
出现在每一页上。使用exact path
阻止了我这样做。它还阻止我使用“/”来渲染Home
。当我将App
的exact path
设置为path
时,我能够做到这一点,但是可以放入任何随机未声明的路线。例如,localhost:3000/poop
不会像我预期的那样呈现NotFound
,它只会渲染什么。
总之,通过将App
移出routes/index
,我可以将其目录包装在根索引文件中的Router
中。然后通过将Routes
导入App
,我可以让我的应用程序更受路由驱动,同时在所有页面上保持Header
。此外,通过将我的所有路由包装在Switch
中并将根路径设为exact path
,我可以正确处理未知路径并使用<Redirect to='404' />
渲染NotFound
组件。
【讨论】:
以上是关于使用 React Router 时无法访问 App 组件的主要内容,如果未能解决你的问题,请参考以下文章
当路由匹配时,React Router 不显示组件(但渲染工作)
使用 create-react-app 将 react-router-dom 添加到 react 应用程序时,为啥玩笑测试会中断