2017-12-22 20 views
0

私は小さな問題を抱えています。ログイン後、ユーザーがログインページにアクセスしようとすると、ホームページにリダイレクトされます。しかし、リダイレクトが発生する前に、/ signinのページが何秒間点滅/表示されるのかが分かりません。私は、コードの流れを説明するために全力を尽くすよコンポーネントの状態は、それ自体が非常に高速になる前にデフォルトに戻されます。

するたびに、ユーザーのログイン、state.signIn.signInSuccessがtrueに設定されています。この状態は私のルートコンポーネントのプロップにマッピングされ、ここで私はAuthorizedRoutesコンポーネントのプロップとして渡します。 authorizedRoutesコンポーネントは、signInSuccessがtrueかどうかをチェックし、/ signinページをレンダリングするか、またはリダイレクトします。 signinページにアクセスしようとすると、signInSuccessは状態が半分の間falseと表示されてから、ユーザーが既にサインインしていてもtrueに変更されます。これは小さな問題ですが、その半分の秒間、falseに変わります。

誰かが私を助けることができれば、私はそれを感謝します。

dispatch(setSignInPending(false)); 
dispatch(setSignInSuccess(true)); 

ものは、それぞれの再描画が発生しますので、あなたsetSignInPending(false)signInPendingはfalseですが、setSignInSuccess(true)していないところレンダリングがあるとき:ありがとう

////signin action creators//// 
import { firebaseApp } from '../firebase.js'; 
import { SIGNIN_PENDING, SIGNIN_SUCCESS, SIGNIN_FAIL } from '../constants/signin.js'; 


const setSignInPending = signInPending => { 
    return{ 
     type:SIGNIN_PENDING, 
     signInPending 
    }; 
}; 

const setSignInSuccess = signInSuccess => { 
    return{ 
     type:SIGNIN_SUCCESS, 
     signInSuccess 
    }; 
}; 

const setSignInFail = signInError => { 
    return{ 
     type:SIGNIN_FAIL, 
     signInError 
    };  
}; 

export const signIn = (email, password) => { 
    return dispatch => { 
     dispatch(setSignInPending(true)); 
     return firebaseApp.auth().signInWithEmailAndPassword(email, password) 
      .then(res => { 
       dispatch(setSignInPending(false)); 
       dispatch(setSignInSuccess(true)); 
      }) 
      .catch(error => { 
       console.log('error', error); 
       dispatch(setSignInPending(false)); 
       dispatch(setSignInFail(error.code)); 
      }) 
    } 
}; 

export const signedIn =() => { 
    return dispatch => { 
     dispatch(setSignInSuccess(true)); 
     dispatch(setSignInFail(null)); 
    }; 
}; 



////signin reducer//// 
import { SIGNIN_PENDING, SIGNIN_SUCCESS, SIGNIN_FAIL } from '../constants/signin.js'; 

const defaultState = { 
    signInPending: false, 
    signInSuccess: false, 
    signInError: null, 
}; 

const signIn = (state = defaultState, action) => { 
    let signInState = null; 
    switch (action.type){ 
     case SIGNIN_PENDING: 
      signInState = { 
       ...state, 
       signInPending: action.signInPending 
      }; 
      return signInState; 
     case SIGNIN_SUCCESS: 
      signInState = { 
       ...state, 
       signInSuccess: action.signInSuccess, 
      }; 
      return signInState; 
     case SIGNIN_FAIL: 
      signInState = { 
       ...state, 
       signInError: action.signInError 
      }; 
      return signInState; 
     default: 
      return state; 
    }; 
}; 

export default signIn; 





////Routes component//// 
class Routes extends React.Component{ 
    constructor(props){ 
     super(props); 
    } 

    componentWillMount(){ 
     firebaseApp.auth().onAuthStateChanged(user => { 
      // user ? dispatch(setSignedInTrue()) : dispatch(setSignedInFalse()); 
      if (user){ 
       this.props.signedIn(); 
      } 
     }); 
    } 

    render(){ 
     return(
      <Router> 
       <Switch> 
        <Route exact path='/' render={(props) => (<App signInSuccess={this.props.signInSuccess} {...props}/>)} /> 
        <AuthorizedRoute signedIn={this.props.signInSuccess} path="/signup" component={SignUp} /> 
        <AuthorizedRoute signedIn={this.props.signInSuccess} path="/signin" component={SignIn} /> 
        <Route component={InvalidPage} /> 
       </Switch> 
      </Router> 
     ); 
    } 
}; 

Routes.propTypes = { 
    signedIn: PropTypes.func.isRequired 
}; 

const mapStateToProps = (state) => { 
    return{ 
     signInSuccess: state.signIn.signInSuccess 
    }; 
}; 

const mapDispatchToProps = (dispatch) => { 
    return{ 
     signedIn:() => dispatch(signedIn()), 
     signOut:() => dispatch(signOut()) 
    }; 
}; 

export default connect(mapStateToProps, mapDispatchToProps)(Routes); 



////AuthorizedRoutes Component//// 
class AuthorizedRoute extends React.Component{ 
    constructor(props){ 
     super(props); 
    }; 

    render(){ 
     console.log(this.props); 
     const { component: Component, ...rest } = this.props; 
     return(
      <Route {...rest} render={props => { 
       if (this.props.signedIn){ 
        return <Redirect to="/" /> 
       } else if (this.props.signedIn === false){ 
        return <Component {...props} /> 
       } else{ 
        return null; 
       } 
      }} /> 
     ); 
    } 
}; 

AuthorizedRoute.propTypes = { 
    signInSuccess: PropTypes.bool 
}; 

export default AuthorizedRoute; 

答えて

0

あなたは2つの別々のReduxの状態変化をトリガ呼び出されました。

これは、単純なゲッター/セッターで使用するReduxの一般的な使用法です。それは、状態の複数の側面を変えることができる出来事のようなものと考えることができます。私はあなたが実際に1つのイベント:signInSuccess(または失敗)を持っていると思う、あなたはあなたが応答を持っていることを知っているので、その減速のケースでは保留をfalseに設定する必要があります。そうすれば、1つのRedux状態の変更だけがあり、レンダリングが呼び出されると、状態は現在と同じように無効な状態にはなりません。

////signin reducer//// 
import { SIGNIN_SUCCESS, SIGNIN_FAIL } from '../constants/signin.js'; 

const defaultState = { 
    signInPending: false, 
    signInSuccess: false, 
    signInError: null, 
}; 

const signIn = (state = defaultState, action) => { 
    let signInState = null; 
    switch (action.type){ 
     case SIGNIN_SUCCESS: 
      signInState = { 
       ...state, 
       signInSuccess: action.signInSuccess, 
       signInPending: false, 
       signInError: null 
      }; 
      return signInState; 
     case SIGNIN_FAIL: 
      signInState = { 
       ...state, 
       signInError: action.signInError, 
       signInPending: false, 
       signInSuccess: false 
      }; 
      return signInState; 
     default: 
      return state; 
    }; 
}; 

export default signIn; 
+0

ありがとうございました。応答を待っているときに保留中のものを使用して、読み込みアニメーションを表示します。保留中でなければ、どうすればいいのか分かりません。また、私はあなたが言っていることを理解していますが、私は私のアクション作成者からsignedIn()を呼び出すときにどのような関係があるのか​​分かりません: 'export const signedIn =()=> { \t return dispatch => { \t \tディスパッチ(setSignInSuccess(true)); \t \tディスパッチ(setSignInFail(null)); \t}; }; 'これは、ログインしたユーザーがページに戻るときに呼び出されます。私は彼らが既にログインしていることを確認し、trueに設定しますが、falseにしてtrueに反転します – Justin

+0

2つの状態の変更がある場合、setSignInSuccess(true)と他のsetSignInFail(null)ユーザーがサインインページにアクセスしようとする前にtrueに設定するとfalseに戻ります – Justin

+0

私は、signInError:null状態の変更をレデューサーに追加しました。また、あなたのsignedInアクションに2つの別々のアクションをディスパッチしません: 'export const signedIn =()=> {return dispatch => {dispatch(setSignInSuccess(true)); }; }; ' – brub

関連する問題