2017-07-08 16 views
0

Reactでログインページを実装しようとしています。私は2つの入力フィールド(IDとパスワード)と送信ボタンを持つログインコンポーネントを持っています。このボタンはMaterial-Uiボタンコンポーネントです。ボタンには、idとパスワードが正しいかどうかを確認するonClickメソッドがあります。その場合は、別のコンポーネントにルーティングする必要があります。React-router v4 route on clickボタン

class Connexion extends React.Component { 
constructor(props) { 
    super(props); 
    this.state = { 
     identifiant: '', 
     password: '', 
     errorMessage: '' 
    }; 

    this.checkIdentifiantAndPassaword = this.checkIdentifiantAndPassword.bind(this); 
    this.handleIdentifiantChange = this.handleIdentifiantChange.bind(this); 
    this.handlePasswordChange = this.handlePasswordChange.bind(this); 
} 
handleIdentifiantChange(e) { 
    this.setState({ 
     identifiant: e.target.value 
    }); 
} 

handlePasswordChange(e) { 
    this.setState({ 
     password: e.target.value 
    }); 
} 
checkIdentifiantAndPassword(e) { 
    let { identifiant, password } = this.state; 
    if (!identifiant) { 
     console.log('check identifiant'); 
     this.setState({ 
      errorMessage: 'Identifiant vide ou incorrect.' 
     }); 
     return; 
    } 
    if (!password) { 
     this.setState({ 
      errorMessage: 'Mot de passe vide ou incorrect.' 
     }); 
     return; 
    } 
    console.log(this.props); 
    this.props.onLogin(true); 
    console.log('Succés'); 
} 
render() { 
    let { errorMessage } = this.state; 
    return (
     <Paper elevation={4} > 
      <Typography type="display2" className="text-center header_title">Connexion</Typography> 
      <div className="row content_container"> 
       <div className="small-4 small-centered columns"> 
        <Typography type="body2" className="loginError">{errorMessage}</Typography> 
        <form> 
         <TextField required value={this.state.identifiant} onChange={this.handleIdentifiantChange} label="Identifiant" type="text" className="txtField" marginForm /> 
         <TextField required value={this.state.password} onChange={this.handlePasswordChange} label="Mot de passe" type="password" className="txtField" marginForm /> 
         <Button raised color="primary" className=" btn" onClick={this.checkIdentifiantAndPassword}>Se connecter</Button> 
        </form> 
       </div> 
      </div> 
     </Paper> 
    ); 
} 

}

私の問題は、onClickハンドラ経由で別のコンポーネントにリダイレクトする方法がわかりません。私は以下のようにNavLinkボタンコンポーネントを包むように多くのソリューションを試してみました:

<NavLink to="/new" ><Button raised color="primary" className=" btn" onClick={this.checkIdentifiantAndPassword}>Se connecter</Button></NavLink> 

しかし、私はcheckIdentifiantAndPasswordメソッドの最初の行でエラーが発生します。

Cannot read property 'state' of null 

私がいることを知っていますボタンコンポーネントを削除して、NavLinkのみを使用し、のすべてのクラスを追加ボタンコンポーネントt o NavLinkしかし、私はこの回避策が嫌いです。

誰かが私がこれをどのように達成できるかという考えを持っていますか?私はReact-router v4を使用しています。 ありがとうございます。

答えて

2

「react-router-dom」の<Redirect/>を使用できます。

ドキュメントでは、(プライベートルートに加えて)使用方法について説明しています。 https://reacttraining.com/react-router/web/example/auth-workflowを参照してください。私は多分あなたは、このようSTHを行うことができると思い

this.state = { 
    ...., 
    doRedirect: false 
} 

..... 

checkIdentifiantAndPassword(e) { 
    ..... 
    this.setState({ 
    doRedirect: true 
    }); 
} 

..... 

render() { 
    if (this.state.doRedirect) { 
    <Redirect to={/*Your next route*/}/> 
    } 
    ..... 
} 
+0

Henriqueありがとうございます。私は他の人のために以下の全体のソリューションを投稿します。 – Alee

0

はあなたの応答とのリンクのためにあなたのエンリケをありがとうございます。それは有用だった。 反応ルートv4で公開ルートとプライベートルートを管理しようとしている人のための私の全体的なソリューションです。

私は2つのプライベートコンポーネント、1つのパブリックコンポーネント(Connexion)をコネクションコンポーネントとし、これらのコンポーネントすべてをラップするメインコンポーネントを持っています。

Connexionコンポーネントは、id、passwordフィールド、および接続が有効かどうかを確認する送信ボタンです。 「はい」の場合、ユーザーはプライベートコンポーネントにルーティングされます。

私は、2つの他のコンポーネントPublicRouteとPrivateRouteも定義します。 PrivateRouteは、ユーザーが有効かどうかをチェックします。はいの場合は、該当するコンポーネントにルーティングします。

主成分

class Main extends React.Component { 
constructor(props) { 
    super(props); 
    this.state = { 
     login: false 
    } 
    super(props); 

    this.handleLogin = this.handleLogin.bind(this); 
    this.handleDeconnexion = this.handleDeconnexion.bind(this);; 
} 
handleDeconnexion(value) { 
    this.setState({ 
     login: value 
    }) 
} 
handleLogin(isAuthenticated) { 
    console.log(isAuthenticated); 
    this.setState(
     { 
      login: isAuthenticated 
     } 
    ); 
} 
render() { 
    let { login } = this.state; 
    return (
     <HashRouter> 
      <div> 
       <Nav isLoggedIn={login} deconnecter={this.handleDeconnexion} /> 
       <div className="row main_container"> 
        <div className="columns medium-10 small-centered"> 
         <PublicRoute exact path="/" component={Connexion} onLogin={this.handleLogin} /> 
         <PrivateRoute isAuthenticated={login} path="/new" component={Nouveau} /> 
         <PrivateRoute isAuthenticated={login} path="/suivi" component={SuiviCas} /> 
        </div> 
       </div> 
      </div> 
     </HashRouter> 
    ); 
} 
} 

Connexionの成分

class Connexion extends React.Component { 
constructor(props) { 
    super(props); 
    this.state = { 
     identifiant: '', 
     password: '', 
     errorMessage: '', 
     doRedirect: false 
    }; 

    this.handleIdentifiantChange = this.handleIdentifiantChange.bind(this); 
    this.handlePasswordChange = this.handlePasswordChange.bind(this); 
    this.handleLogin = this.handleLogin.bind(this); 
} 

handleIdentifiantChange(e) { 
    this.setState({ 
     identifiant: e.target.value 
    }); 
} 

handlePasswordChange(e) { 
    this.setState({ 
     password: e.target.value 
    }); 
} 
handleLogin(e) { 
    let { identifiant, password } = this.state; 
    if (!identifiant) { 
     this.setState({ 
      errorMessage: 'Identifiant vide ou incorrect.' 
     }); 
     return; 
    } 
    if (!password) { 
     this.setState({ 
      errorMessage: 'Mot de passe vide ou incorrect.' 
     }); 
     return; 
    } 
    this.setState({ 
     doRedirect: true 
    }); 
    this.props.onLogin(true); 
} 
render() { 
    const { from } = this.props.location.state || { from: { pathname: '/thecomponent_you_want_to_redirect_after_login'} 
    let{ doRedirect, errorMessage } = this.state; 
    if (doRedirect) { 
     return (
      <Redirect to={from} /> 
     ) 
    } 
    return (
     <Paper elevation={4} > 
      <Typography type="display2" className="text-center header_title">Connexion</Typography> 
      <div className="row content_container"> 
       <div className="small-4 small-centered columns"> 
        <Typography type="body2" className="loginError">{errorMessage}</Typography> 
        <form> 
         <TextField required value={this.state.identifiant} onChange={this.handleIdentifiantChange} label="Identifiant" type="text" className="txtField" marginForm /> 
         <TextField required value={this.state.password} onChange={this.handlePasswordChange} label="Mot de passe" type="password" className="txtField" marginForm /> 
         <Button raised color="primary" className=" btn" onClick={this.handleLogin}>Se connecter</Button> 
        </form> 
       </div> 
      </div> 
     </Paper> 
    ); 
} 
} 

PrivateRoute成分チェックユーザが認証され、適切なルートにリダイレクトされた場合。そうでない場合は、Connexionコンポーネントにルーティングされます。 React router v4:ここ

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

PublicRouteコンポーネント

const PublicRoute = ({ component: Component, onLogin, ...rest }) => (
<Route {...rest} render={props => (

    <Component onLogin={onLogin} {...props} /> 
)} /> 
); 

が反応し、ルータをV4とv2とのいくつかの相違点を説明する便利ユーチューブリンクです。