2017-12-20 18 views
3

개인 프로젝트에서 작업하고 있는데 사용자가 로그인했는지 여부를 확인하는 데 문제가있어/로그인하려고 시도 할 때 홈페이지로 리디렉션하십시오. 현재 어떤 내 코드가하는 일은 다음과 같습니다React-Redux 리디렉션 전에 페이지가 렌더링되지 않도록하는 방법

  1. 것은 checkIfSignedIn가 호출 될 때, 참 또는 거짓으로 isLoggedIn 상태를 설정 작업을 전달 내 자신의 경로 구성 요소
  2. 을 정의.
  3. AuthenticatedRouter 구성 요소는 저장소의 isLoggedIn 상태가 true 또는 false인지 확인하고 구성 요소를 렌더링하거나 집으로 리디렉션합니다.
  4. 이것은 작동하지만 문제는 isLoggedIn이 처음에는 false이므로 로그인하면 초 단위로 표시되고 isLoggedIn이 true가 된 후 리디렉션됩니다.

구성 요소가 기본 상태로 렌더링되는 문제를 해결하는 방법을 알 수 없으며 상태가 변경되어 갑자기 리디렉션됩니다. 감사합니다

  • 나는 사용자 계정에 firebase를 사용하고 있습니다.

Routes.js

const Routes = (props) => { 
    props.checkIfSignedIn(); 
    return(
     <Router> 
      <Switch> 
       <Route exact path='/' component={App}/> 
       <AuthorizedRoute path="/signup" component={SignUp}/> 
       <AuthorizedRoute path="/signin" component={SignIn}/> 
       <Route component={InvalidPage}/> 
      </Switch> 
     </Router> 
    ); 
}; 

const mapDispatchToProps = (dispatch) => { 
    return{ 
     checkIfSignedIn:() => dispatch(checkIfSignedIn()) 
    }; 
}; 

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

AuthorizedRoute.js

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

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


const mapStateToProps = (state) => { 
    return{ 
     isLoggedIn : state.authentication.isLoggedIn 
    }; 
}; 

export default connect(mapStateToProps, null)(AuthorizedRoute); 

authentication.js - 액션 제작자

const setSignedInFalse =() => { 
    return{ 
     type: IS_SIGNED_IN_FALSE 
    }; 
}; 

const setSignedInTrue =() => { 
    return{ 
     type: IS_SIGNED_IN_TRUE 
    }; 
}; 

const checkIfSignedIn =() => { 
    return dispatch => { 
     firebaseApp.auth().onAuthStateChanged(user => { 
      if (user){ 
       dispatch(setSignedInTrue()); 
      } else{ 
       dispatch(setSignedInFalse()); 
      } 
     }); 
    }; 
}; 

export default checkIfSignedIn; 

authentication.js - 감속기

,
const defaultState = { 
    isLoggedIn: false 
}; 

const authentication = (state = defaultState, action) => { 
    let authenticationState = null; 
    switch (action.type){ 
     case IS_SIGNED_IN_FALSE: 
      authenticationState = { 
       isLoggedIn: false 
      }; 
      return authenticationState; 
     case IS_SIGNED_IN_TRUE: 
      authenticationState = { 
       isLoggedIn: true 
      }; 
      return authenticationState; 
     default: 
      return state; 
    }; 
}; 

export default authentication; 

해키 솔루션 (이것이 싫은지 확실하지 않은 경우).

필자는 Auth 감속기의 기본 상태 인 isLoggedIn : false 대신 null을 설정했습니다. 그런 다음 내 AuthorizedRoute 구성 요소에는 이제 null을 먼저 렌더링 한 다음 구성 요소 또는 리디렉션을 렌더링하는 세 가지 조건이 있습니다.

//AuthorizedRoute Component 
if (this.props.isLoggedIn){ 
    return <Redirect to="/" /> 
} else if (this.props.isLoggedIn === false){ 
    return <Component {...props} /> 
} else{ 
    return null; 
} 
+0

개인적으로 '해킹 된 솔루션'을 싫어합니다. loggedIn = true, loggedIn = false, loggedIn = 초기화되지 않은 세 가지 상태가 있습니다. 무엇을 렌더링 할까 모르는 경우는 null를 렌더링한다 (또는로드 중의 인디케이터). – brub

답변

1

다음과 같이 할 수 있습니다 (인증 감속기에서).

let user = JSON.parse(localStorage.getItem('user')); 
const initialState = user ? { isLoggedIn: true } : {}; 

또한 사용자가 로그인 할 때 localstorage를 설정하고 로그 아웃 할 때 제거해야합니다.

+0

그럴 수 있습니다. 필자가 우려하는 한 가지는 현재 Firebase의 firebaseApp.auth(). onAuthStateChanged를 사용하여 사용자가 로그인했는지 확인하기 때문에 대부분의 작업을 변경하지 않아도됩니다. – Justin

+0

어떻게 행동 (이런 일을) firebaseApp.auth()는 로컬 스토리지를 추가하는 방법에 대한 onAuthStateChanged (사용자 => { 경우 (사용자) { 파견 (setSignedInTrue());. localStorage.setItem가 ('사용자', JSON.stringify ({user : user})); } else { dispatch (setSignedInFalse()); localStorage.removeItem ('user'); } }); –

+0

고마워요, 이것에 대해 살펴 보겠습니다. 위의 편집 솔루션을 살펴보고 생각을 말해도 될까요? 다시 한번 감사드립니다 – Justin

1
class AuthorizedRoute extends React.Component{ 
    constructor(props){ 
     super(props); 
     this.state = { 
      isLoggedIn: false 
     }; 
    }; 

    render(){ 
     const { component: Component, ...rest } = this.props; 
     const user = JSON.parse(localStorage.user); 
     return (
      <Route {...rest} render={props => user ? <Component {...props} /> : <App /> } /> 
     ); 
    } 
}; 


const mapStateToProps = (state) => { 
    return{ 
     isLoggedIn : state.authentication.isLoggedIn 
    }; 
}; 

export default connect(mapStateToProps, null)(AuthorizedRoute); 
+0

localStorage에 사용자 로그인을 저장하고이를 확인하기 때문에이 솔루션을 사용한다면 AuthorizedRoute에 redux 상태를 사용할 필요가 없을 것입니다. – Justin

+0

그래, 당신은 복급 국가가 필요 없을거야. –