2017-04-14 29 views
1

我試圖遷移到使用React Router 4並且在理解<Switch>組件的邏輯時遇到了一些麻煩,因爲它在docs中用於處理404(或不匹配的)路線。<Switch>組件在react-router-4中匹配null值

對於我的條目JavaScript文件,我設置了以下路線。

index.js

<Switch> 
    <Route path="/login" component={Login} /> 
    <Route path="/forgot-password" component={ForgotPassword} /> 
    <Route path="/email-verification" component={EmailVerification} /> 
    <Route component={App} /> 
</Switch> 

Login組件將檢查以查看是否用戶被驗證,並且如果是這樣,將用戶重定向到該/dashboard路徑(經由history.replace)。

App組件僅在用戶通過身份驗證時纔可訪問,並且它具有類似的檢查以將用戶重定向到/login(如果不是)。

在我App組件我有更多的規定航線上,我可以肯定的是隻訪問,如果用戶登錄。

App.js

<Switch> 
    <Route path="/dashboard" component={Dashboard} /> 
    <Route path="/accounts" component={Account} /> 
    <Authorize permissions={['view-admin']}> 
     <Route path="/admin" component={Admin} /> 
    </Authorize> 
    <Route path="/users" component={Users} /> 
    <Route component={NotFound} /> 
</Switch> 

就在這裏我的問題 。對通過權限的Authorize組件會檢查用戶是否有這些權限,如果是這樣,它使孩子們直接,如果不是,則返回從render()null

此處的預期行爲是,<Route path="/admin" />在沒有足夠權限且<Route component={NotFound} />組件呈現時根本不呈現。

按照docs

呈現一個相匹配的第一個孩子。 A 沒有路徑總是匹配。

但是,如果我去任何航線宣告<Authorize>組件後,路由器匹配null。這意味着,根據上面的例子,去/users返回null。預期行爲是否會返回<Switch/>組件中的第一個匹配項,即使它的值爲null

我該如何爲這種情況提供一個「全部通過」路由(404),而不需要爲App.js中的許多經過身份驗證的路由創建一個<PrivateRoute>組件?一個null值應該真的產生一個匹配?

+0

我有同樣的問題。你有沒有找到這方面的解決方案? – Salim

+0

我相信這個問題是由於我的組件造成的,但我從未發現這是爲什麼會出現這種情況。 – Himmel

回答

1

不幸的是,react-router的Switch組件不能與嵌套在其他組件中的路由一起工作,就像你的例子。如果檢查the docs for Switch,它說:

一個<開關>的所有的孩子都應該是<路線>或<重定向>元素。

...因此,您的Authorize組件實際上並不是合法的,因爲它是Switch的直接子項。

如果你有過the source code of the Switch component讀,你會看到它,而邪惡地讀取它的每一個孩子的道具和手動對每個孩子的path(或from)道具適用反應路由器的matchPath方法,以確定哪些人應被渲染。

因此,你的情況發生了什麼是Switch迭代通過它的孩子,直到它到達你的Authorize組件。然後它查看該組件的道具,找不到pathfrom道具,並在未定義的路徑上調用matchPath。當你注意到自己,「<路徑>沒有路徑總是匹配」,所以matchPath返回true,並且開關呈現您的Authorize組件(忽略任何後續的路由或重定向,因爲它認爲它找到了匹配)。但是,Authorize組件中嵌套的「/ admin」路由與當前路徑不匹配,因此您會從渲染中返回空結果。

我在工作中遇到類似的情況。我計劃解決這個問題的方法是在我的路由代碼中用一個自定義組件替換react路由器的Switch,該自定義組件會遍歷其子代,然後依次手動渲染每個代碼,並返回第一個返回非空值的結果。當我給它一個鏡頭時,我會更新這個答案。

編輯:那麼,沒有工作。我無法制定出一種支持的方式來手動調用子項上的「渲染」。對不起,我無法給你解決Switch的限制。