前提・実現したいこと
react-router を使ったログイン処理を作りたいです。
セッションチェック用に Auth コンポーネントを作成しており、
ログイン時は子コンポーネントへルーティングし、非ログイン時はログイン画面へリダイレクトするような実装になっています。
ログインボタンを押した際にログイン用のAPIを飛ばし、Auth コンポーネントでログインチェック用のAPIを飛ばしています。
認証はJWTを使っており、トークンはローカルストレージで管理する実装になっています。
また、Auth コンポーネントにて、ログインチェック用のAPIを呼ぶ際は Effect Hook を使っています。
発生している問題・エラーメッセージ
ログイン画面にアクセスして、ログインした場合は想定通りログインできるものの、
リダイレクト後はログインしようとしてもトークンをローカルストレージにセットするのみで処理が終わってしまいます。
調べたところリダイレクト時の処理の順番が
Auth コンポーネントがマウントされた後に、ログインチェック用のAPIが走っていました。
また、この順番はログイン画面に直接アクセスした場合も発生しており、しかしその場合はさらにその後にAuthコンポーネントがマウントされていたため、ルーティングがうまくいっておりました。
質問としてお聞きしたいことは以下の2点になります。
0. なぜリダイレクト時は動作が異なるのでしょうか。
0. ログインチェックの実装としてもっといい方法があれば知りたいです。
該当のソースコード
以下がコンポーネントファイルです。
TypeScript
1import * as React from 'react' 2import { Route, Redirect } from 'react-router' 3import { CLIENT_URI, LOGIN_URI } from '../constants' 4import { useAuthHook } from '../hooks/authHook' 5 6interface AuthProps { 7 children: React.ReactNode 8} 9 10export const AuthComponent: React.SFC<AuthProps> = (props) => { 11 const auth = useAuthHook() 12 13 return ( 14 <div> 15 {auth.isLoading 16 ? (<div />) 17 : auth.isAuth 18 ? (<Route children={props.children} />) 19 : (<Redirect to={CLIENT_URI + LOGIN_URI} />) 20 } 21 </div> 22 ) 23}
Hook ファイルです。
typescript
1import { useEffect } from 'react' 2import { useSelector } from 'react-redux' 3import { AppState } from '../store' 4import useActions from '../useActions' 5import { checkLogedIn } from '../actions/authAction' 6 7export const useAuthHook = () => { 8 const auth = useSelector((state: AppState) => state.auth) 9 const [checkAuth] = useActions([checkLogedIn], []) 10 11 useEffect(() => { 12 checkAuth() 13 }, [checkAuth]) 14 return auth 15}
Action ファイルです。
TypeScript
1import actionCreatorFactory, { Action } from 'typescript-fsa' 2import { Dispatch } from 'react' 3import { myInfo } from '../apiService' 4 5const actionCreator = actionCreatorFactory() 6 7export const authActions = { 8 updateIsAuth: actionCreator<boolean>('ACTIONS_UPDATE_IS_AUTH'), 9 updateIsLoading: actionCreator<boolean>('ACTION_UPDATE_ISLOADING') 10} 11 12export const checkLogedIn = () => { 13 return async (dispatch: Dispatch<Action<boolean>>) => { 14 return myInfo().then(() => { 15 dispatch(authActions.updateIsAuth(true)) 16 dispatch(authActions.updateIsLoading(false)) 17 }).catch(() => { 18 dispatch(authActions.updateIsAuth(false)) 19 dispatch(authActions.updateIsLoading(false)) 20 }) 21 } 22}
試したこと
ログイン処理の同期非同期を弄ったりしましたが、あまり関係なさそうでした。
他は発生している問題でコンソールに出力して順番等を確認してみた程度です。
正直なぜリダイレクト時で動作が違うのかわかっていないので、何をすれば解決するのかの糸口が見えていません。
補足情報(FW/ツールのバージョンなど)
react: 16.11.0
react-router-dom: 5.1.2
redux: 4.0.4
typescript": 3.6.4
あなたの回答
tips
プレビュー