Kimliği doğrulanmış rotalar uygulamaya çalışıyordum ancak React Router 4'ün artık bunun çalışmasını engellediğini fark ettim:
<Route exact path="/" component={Index} />
<Route path="/auth" component={UnauthenticatedWrapper}>
<Route path="/auth/login" component={LoginBotBot} />
</Route>
<Route path="/domains" component={AuthenticatedWrapper}>
<Route exact path="/domains" component={DomainsIndex} />
</Route>
Hata şu:
Uyarı: Aynı rotada
<Route component>
ve<Route children>
kullanmamalısınız;<Route children>
göz ardı edilecektir
Bu durumda, bunu uygulamanın doğru yolu nedir?
Bu react-router
(v4) dokümanlarında görünüyor, şöyle bir şey öneriyor
<Router>
<div>
<AuthButton/>
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Route path="/public" component={Public}/>
<Route path="/login" component={Login}/>
<PrivateRoute path="/protected" component={Protected}/>
</div>
</Router>
Ancak bir grup rotayı bir araya getirirken bunu başarmak mümkün mü?
GÜNCELLEME
Tamam, biraz araştırdıktan sonra bunu buldum:
import React, {PropTypes} from "react"
import {Route} from "react-router-dom"
export default class AuthenticatedRoute extends React.Component {
render() {
if (!this.props.isLoggedIn) {
this.props.redirectToLogin()
return null
}
return <Route {...this.props} />
}
}
AuthenticatedRoute.propTypes = {
isLoggedIn: PropTypes.bool.isRequired,
component: PropTypes.element,
redirectToLogin: PropTypes.func.isRequired
}
Bir eylemi render()
içinde göndermek doğru mu, yanlış geliyor. ComponentDidMount` veya başka bir kanca ile de gerçekten doğru görünmüyor mu?
Redirectbileşenini kullanmak isteyeceksiniz. Bu soruna birkaç farklı yaklaşım var. İşte benim sevdiğim bir tanesi, bir
authed` prop'u alan ve daha sonra bu prop'a göre render eden bir PrivateRoute bileşenine sahip olmak.
function PrivateRoute ({component: Component, authed, ...rest}) {
return (
<Route
{...rest}
render={(props) => authed === true
? <Component {...props} />
: <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
/>
)
}
Şimdi Route
larınız aşağıdaki gibi görünebilir
<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authed={this.state.authed} path='/dashboard' component={Dashboard} />
Eğer hala kafanız karışıksa, size yardımcı olabilecek bu yazıyı yazdım - React Router v4 ile korumalı rotalar ve kimlik doğrulama
Çözüm için teşekkürler Tyler McGinnis. Fikrimi Tyler McGinnis'in fikrinden aldım.
const DecisionRoute = ({ trueComponent, falseComponent, decisionFunc, ...rest }) => {
return (
<Route
{...rest}
render={
decisionFunc()
? trueComponent
: falseComponent
}
/>
)
}
Bunu şu şekilde uygulayabilirsiniz
<DecisionRoute path="/signin" exact={true}
trueComponent={redirectStart}
falseComponent={SignInPage}
decisionFunc={isAuth}
/>
decisionFunc sadece doğru veya yanlış döndüren bir fonksiyon
const redirectStart = props => <Redirect to="/orders" />
Görünüşe göre tereddütünüz kendi bileşeninizi oluşturmak ve ardından render yönteminde göndermek mi? Sadece <Route>
bileşeninin render
yöntemini kullanarak her ikisinden de kaçınabilirsiniz. Gerçekten istemediğiniz sürece bir <AuthenticatedRoute>
bileşeni oluşturmanıza gerek yok. Aşağıdaki kadar basit olabilir. Route>bileşeninin özelliklerini alt bileşene (bu durumda
) göndermeye devam ettiğinizden emin olmak için
{...routeProps}` yayılımına dikkat edin.
<Route path='/someprivatepath' render={routeProps => {
if (!this.props.isLoggedIn) {
this.props.redirectToLogin()
return null
}
return <MyComponent {...routeProps} anotherProp={somevalue} />
} />
Bakınız React Router V4 render belgeleri
Eğer özel bir bileşen oluşturmak istediyseniz, o zaman doğru yoldasınız gibi görünüyor. React Router V4 tamamen bildirimsel yönlendirme olduğu için (açıklamasında öyle yazıyor) yönlendirme kodunuzu normal bileşen yaşam döngüsünün dışına koyarak kurtulabileceğinizi sanmıyorum. React Router'ın kendi koduna]3 baktığımızda, yönlendirmeyi sunucu tarafı işleme olup olmamasına bağlı olarak componentWillMount
ya da componentDidMount
içinde gerçekleştiriyorlar. İşte oldukça basit olan ve yönlendirme mantığınızı nereye koyacağınız konusunda kendinizi daha rahat hissetmenize yardımcı olabilecek aşağıdaki kod.
import React, { PropTypes } from 'react'
/**
* The public API for updating the location programatically
* with a component.
*/
class Redirect extends React.Component {
static propTypes = {
push: PropTypes.bool,
from: PropTypes.string,
to: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
])
}
static defaultProps = {
push: false
}
static contextTypes = {
router: PropTypes.shape({
history: PropTypes.shape({
push: PropTypes.func.isRequired,
replace: PropTypes.func.isRequired
}).isRequired,
staticContext: PropTypes.object
}).isRequired
}
isStatic() {
return this.context.router && this.context.router.staticContext
}
componentWillMount() {
if (this.isStatic())
this.perform()
}
componentDidMount() {
if (!this.isStatic())
this.perform()
}
perform() {
const { history } = this.context.router
const { push, to } = this.props
if (push) {
history.push(to)
} else {
history.replace(to)
}
}
render() {
return null
}
}
export default Redirect