问题描述
我试图将我的大多数路线呈现为AppShell
组件的子项,该组件包含一个导航栏.但是我想将我的404路由呈现为不包装在AppShell
中的独立组件.
I'm trying to render most of my routes as children of an AppShell
component, which contains a navbar. But I want to render my 404 route as a standalone component not wrapped in AppShell
.
<Router>
<Route component={AppShell}>
<Route path="/about" component={About} />
<Route path="/" component={Home} />
</Route>
<Route path="*" component={NotFound} />
</Router>
一切都按要求进行:
-
/
呈现<AppShell><Home /></AppShell>
-
/about
呈现<AppShell><About /></AppShell>
-
/blah
呈现<NotFound />
/
renders<AppShell><Home /></AppShell>
/about
renders<AppShell><About /></AppShell>
/blah
renders<NotFound />
现在我正在执行此操作,但问题是它呈现了AppShell
(没有子项,但仍然有导航栏):
Right now I'm doing this, but the problem is it renders AppShell
(with no children, but still a navbar):
const Routes = () => (
<div>
<AppShell>
<Match exactly pattern="/" component={Home} />
<Match pattern="/about" component={About} />
</AppShell>
<Miss component={NotFound} />
</div>
)
与此:
-
/
呈现<div><AppShell><Home /></AppShell></div>
(良好) -
/about
呈现<div><AppShell><About /></AppShell></div>
(良好) -
/blah
渲染<div><AppShell /><NotFound /></div>
(问题-我想摆脱<AppShell />
)
/
renders<div><AppShell><Home /></AppShell></div>
(good)/about
renders<div><AppShell><About /></AppShell></div>
(good)/blah
renders<div><AppShell /><NotFound /></div>
(problem -- I want to get rid of the<AppShell />
)
const InAppShell = (): React.Element<any> => (
<AppShell>
<Match pattern="/about" component={About} />
<Match pattern="/contact" component={Contact} />
</AppShell>
)
const App = (): React.Element<any> => (
<div>
<Match pattern={['/contact', '/about']} component={InAppShell} />
<Miss component={NotFound} />
</div>
)
并且将数组pattern
与exactly
一起使用可用于根路由:
但是然后我必须将所有可能的子路线放在pattern
数组中...
And using an array pattern
with exactly
works with the root route:
But then I have to put all possible child routes in the pattern
array...
const InAppShell = (): React.Element<any> => (
<AppShell>
<Match exactly pattern="/" component={Home} />
<Match pattern="/about" component={About} />
</AppShell>
)
const App = (): React.Element<any> => (
<div>
<Match exactly pattern={["/", "/about"]} component={InAppShell} />
<Miss component={NotFound} />
</div>
)
但是在具有大量路由的大型应用程序中,这将是非常不必要的.
But that would be pretty unwieldly in a large app with a bunch of routes.
const InAppShell = (): React.Element<any> => (
<AppShell>
<Match exactly pattern="/" component={Home} />
<Match pattern="/about" component={About} />
<Match pattern="/contact" component={Contact} />
</AppShell>
)
const App = (): React.Element<any> => (
<div>
<Match exactly pattern="/" component={InAppShell} />
<Match pattern={["/about", "/contact"]} component={InAppShell} />
<Miss component={NotFound} />
</div>
)
但是,每次我往返于本国路线时,都会重新安装<AppShell>
.
But this would remount <AppShell>
every time I transition to and from the home route.
这里似乎没有理想的解决方案;我认为这是v4需要解决的一个基本的API设计挑战.
There doesn't seem to be an ideal solution here; I think this is a fundamental API design challenge v4 will need to solve.
如果我能做类似<Match exactlyPattern="/" pattern={["/about", "/contact"]} component={InAppShell} />
...
If only I could do something like <Match exactlyPattern="/" pattern={["/about", "/contact"]} component={InAppShell} />
...
推荐答案
我一直在解决同一个问题-我认为您可能想要这样的东西,即全局404":
I've been working around the same issue - I think you may want something like this, a 'global 404':
https://codepen.io/pshrmn/pen/KWeVrQ
const {
HashRouter,
Route,
Switch,
Link,
Redirect
} = ReactRouterDOM
const Global404 = () => (
<div>
<h1>Oh, no!</h1>
<p>You weren't supposed to see this... it was meant to be a surprise!</p>
</div>
)
const Home = () => (
<div>
The links to "How?" and "Random" have no matching routes, so if you click on either of them, you will get a "global" 404 page.
</div>
)
const Question = ({ q }) => (
<div>
<div>Question: {q}</div>
<div>Answer: I have no idea</div>
</div>
)
const Who = () => <Question q={"Who?"}/>
const What = () => <Question q={"What?"}/>
const Where = () => <Question q={"Where?"}/>
const When = () => <Question q={"When?"}/>
const Why = () => <Question q={"Why?"}/>
const RedirectAs404 = ({ location }) =>
<Redirect to={Object.assign({}, location, { state: { is404: true }})}/>
const Nav = () => (
<nav>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/faq/who'>Who?</Link></li>
<li><Link to='/faq/what'>What?</Link></li>
<li><Link to='/faq/where'>Where?</Link></li>
<li><Link to='/faq/when'>When?</Link></li>
<li><Link to='/faq/why'>Why?</Link></li>
<li><Link to='/faq/how'>How?</Link></li>
<li><Link to='/random'>Random</Link></li>
</ul>
</nav>
)
const App = () => (
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/faq' component={FAQ}/>
<Route component={RedirectAs404}/>
</Switch>
)
const FAQ = () => (
<div>
<h1>Frequently Asked Questions</h1>
<Switch>
<Route path='/faq/who' component={Who}/>
<Route path='/faq/what' component={What}/>
<Route path='/faq/where' component={Where}/>
<Route path='/faq/when' component={When}/>
<Route path='/faq/why' component={Why}/>
<Route component={RedirectAs404}/>
</Switch>
</div>
)
ReactDOM.render((
<HashRouter>
<div>
<Nav />
<Route render={({ location }) => (
location.state && location.state.is404
? <Global404 />
: <App />
)}/>
</div>
</HashRouter>
), document.getElementById('root'))
这篇关于react-router v4:当子路由未命中时如何避免呈现父路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!