React Router 4'te kimliği doğrulanmış rotalar nasıl uygulanır?

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?

Çözüm

Redirectbileşenini kullanmak isteyeceksiniz. Bu soruna birkaç farklı yaklaşım var. İşte benim sevdiğim bir tanesi, birauthed` 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 (
     authed === true
        ? 
        : }
    />
  )
}

Şimdi Routelarınız aşağıdaki gibi görünebilir




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

Yorumlar (21)

Çözüm için teşekkürler Tyler McGinnis. Fikrimi Tyler McGinnis'in fikrinden aldım.

const DecisionRoute = ({ trueComponent, falseComponent, decisionFunc, ...rest }) => {
  return (

  )
}

Bunu şu şekilde uygulayabilirsiniz

decisionFunc sadece doğru veya yanlış döndüren bir fonksiyon

const redirectStart = props => 
Yorumlar (0)

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 bileşeninin `render` yöntemini kullanarak her ikisinden de kaçınabilirsiniz. Gerçekten istemediğiniz sürece bir 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.

 {

   if (!this.props.isLoggedIn) {
      this.props.redirectToLogin()
      return null
    }
    return 

} />

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
Yorumlar (0)