web-dev-qa-db-fra.com

Conversion de React composant de fonction en problème de composant de classe

J'ai le composant fonctionnel react suivant pour aider à prendre en charge les routes d'authentification requises avec react-router.

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    isAuthenticated() ? ( 
        <Component {...props}/>
    ) : (
        <Redirect to={{
            pathname: '/login', 
            state: {from: props.location }
        }}/>
    )
  )}/>
)

J'ai besoin de convertir cela d'un composant fonctionnel en un composant de classe afin de pouvoir profiter de la méthode componentDidMount de React.Component. Malheureusement, j'ai du mal à comprendre comment migrer cela. Si je le prends tel quel, je dois répliquer les paramètres Component et ... rest, mais je ne sais pas comment faire. Je pense que je peux obtenir le paramètre Component avec this.props.component, mais je ne sais pas comment tirer ... reste. Je suis nouveau sur JSX et ES6, donc toute aide ou conseil serait très apprécié.

13
Chris Dellinger

Il n'y a vraiment rien de difficile. Le composant fonctionnel est la fonction render, donc:

class PrivateRoute extends React.Component {
    render() {
       const {component: Component, ...rest} = this.props;

       return (
           <Route {...rest} render={props => (
               isAuthenticated() ? ( 
                 <Component {...props}/>
           ) : (
            <Redirect to={{
                pathname: '/login', 
                state: {from: props.location }
            }}/>
           )
         )}/>
       );
    }
}

ou, écrit un peu plus lisible:

class PrivateRoute extends React.Component {
    render() {
       const {component: Component, ...rest} = this.props;

       const renderRoute = props => {
           if (isAuthenticated()) {
              return (
                  <Component {...props} />
              );
           }

           const to = {
               pathname: '/login', 
               state: {from: props.location}
           };

           return (
               <Redirect to={to} />
           );
       }

       return (
           <Route {...rest} render={renderRoute}/>
       );
    }
}
21
Sulthan

Un refactorisateur agréable et propre en étendant le composant Route:

class PrivateRoute extends Route {

    render() {
        return isAuthenticated()
            ? super.render()
            : <Redirect to={{
                pathname: '/login',
                state: {from: props.location}
            }}/>;
    }
}

Si vous l'utilisez, vous devez envelopper votre <PrivateRoute/>s dans un <Switch/>, comme ci-dessous. Sinon, vous aurez des redirections en double et la page ne se chargera pas.

<Router>
    <Navbar/>
    <SideDrawer/>
    <Switch>
        <Route              path="/tokens"   component={Login}/>
        <PrivateRoute exact path="/"         component={ExampleComponent}/>
        <PrivateRoute       path="/users"    component={Users}/>
        <PrivateRoute       path="/software" component={Software}/>
    </Switch>                   
</Router>
1
Cameron Hudson