我正在构建React应用。如果用户输入错误的URL,则显示NoMatch
组件(很好)。
挑战是当用户键入现有URL时,将显示两个组件。 NoMatch
组件和期望的组件都出现。
注意:我在stackoverflow上发现了一些与此有关的问题,但是没有一种解决方案适合我。我正在使用<PrivateRoute>
和react-router-dom
。
App.js
<Provider store={store}>
<Router>
<Switch>
<Route exact path="/login" component={Login}/>
<Fragment>
<Navigationbar/>
<div className="main-part">
<Sidebar/>
<main className="content shrunk-sidebar">
<PrivateRoute path="/" exact component={Home}/>
<PrivateRoute path="/files" exact component={Files}/>
<PrivateRoute path="/new_app" exact component={NewApp}/>
<PrivateRoute path="/applications/:app_name" exact component={Application} />
<PrivateRoute path="*" component={NoMatch}/>
</main>
</div>
</Fragment>
</Switch>
</Router>
</Provider>
PrivateRoute.js
const PrivateRoute = ({component: Component, auth, ...rest}) => (
<Route
{...rest}
render={props =>
auth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: {from: props.location}
}}
/>
)
}
/>
);
知道我做错了什么而没有得到想要的结果吗?
[Switch
仅适用于它的直接子代,当在其中添加Fragment
之类的东西时,Switch对其内部的Route
组件失去作用。
在您的情况下,您可以简单地将Switch
移到其中以包含PrivateRoute
组件的数组以使其起作用
<Provider store={store}>
<Router>
<Switch>
<Route exact path="/login" component={Login}/>
<Fragment>
<Navigationbar/>
<div className="main-part">
<Sidebar/>
<main className="content shrunk-sidebar">
<Switch>
<PrivateRoute path="/" exact component={Home}/>
<PrivateRoute path="/files" exact component={Files}/>
<PrivateRoute path="/new_app" exact component={NewApp}/>
<PrivateRoute path="/applications/:app_name" exact component={Application}/>
<PrivateRoute path="*" component={NoMatch}/>
</Switch>
</main>
</div>
</Fragment>
</Switch>
</Router>
</Provider>
一种方法是为“正确的”路径添加一个包装组件,该组件将检查如果路径名是正确的路径之一,则呈现其子组件,否则呈现组件。快速示例:
<WrappingComponent>
<Route component={Home} exact path='/' />
<Route component={SomePage} path='/some-page' />
</WrappingComponent>
然后在包装组件路径名中检查:
if (this.props.location.pathname === '/' ||
this.props.location.pathname === '/some-page') {
return this.props.children;
} else {
return <NoMatch />;
}
从中删除路径
<Provider store={store}>
<Router>
<Switch>
<Route exact path="/login" component={Login}/>
<Fragment>
<Navigationbar/>
<div className="main-part">
<Sidebar/>
<main className="content shrunk-sidebar">
<PrivateRoute path="/" exact component={Home}/>
<PrivateRoute path="/files" exact component={Files}/>
<PrivateRoute path="/new_app" exact component={NewApp}/>
<PrivateRoute path="/applications/:app_name" exact component={Application} />
<PrivateRoute component={NoMatch}/>
</main>
</div>
</Fragment>
</Switch>
</Router>
</Provider>
从中删除路径
<Provider store={store}>
<Router>
<Switch>
<Route exact path="/login" component={Login}/>
<Fragment>
<Navigationbar/>
<div className="main-part">
<Sidebar/>
<main className="content shrunk-sidebar">
<PrivateRoute path="/" exact component={Home}/>
<PrivateRoute path="/files" exact component={Files}/>
<PrivateRoute path="/new_app" exact component={NewApp}/>
<PrivateRoute path="/applications/:app_name" exact component={Application} />
<PrivateRoute component={NoMatch}/>
</main>
</div>
</Fragment>
</Switch>
</Router>
</Provider>