2017-07-12 1 views
0

私はreact-routeronEnterフックを使って認証をチェックしようとしています。 基本的には、onEnterフックでSSOログインを開始するために、Reduxストアにサガアクションをディスパッチします。反応ルータonEnterの状態変化を待つ方法は?

しかし、私は認証に成功するとリダイレクトされますが、これはコンポーネントがマウントされた直後に発生するため、ちらつきがあります。 onEnterフックのcallbackを呼び出す前に認証状態を確認しようとしましたが、それでも機能しませんでした。

私のようにフックを適用します。

<Route path='home' component={HomePage} onEnter={checkAuthentication(store)} /> 

、その後、私はそれを実装:私のサガで

const checkAuthentication = (store) => { 
    return (nextState, replace, next) => { 
    if (!store.getState().authentication.isAuthenticated) 
     store.dispatch(checkAuth()) 
    return next() 
    } 
} 

を、私は持っている:

const isAuthenticated = yield call(getAuthenticationToken) // returns a promise which resolves when the user has successfully authenticated on the SSO page 
yield put(actions.checkAuthSuccess(isAuthenticated)) 

どのように私はそれを確認することができますサガが認証ステータスを返さない限り、コンポーネントはマウントされませんか?

ご協力いただければ幸いです。

答えて

1

問題は、サガが非同期であることです。認証チェックはイベントループに委任され、保護されたコンポーネントがマウント/更新された後に実行されます。この状況に対処するための最良の方法は、保護されたルートのゲートキーパーとして機能するルートとコンポーネントを作成することです。

保護されたコンポーネントに最初にルーティングするのではなく、最初に読み込みモーダル(または空白なもの)を持つコンポーネントに送信します。そこから、認証ロジックが完了すると、保護されたルートにルーティングされるか、またはそれらのルートから起動されます。

ユーザーが多くルーティングする必要がある場合、これは実行可能な解決策ではないため、最初の認証チェック後にそのチェックを同期させる方法を見つける方がよいでしょう。そうすれば、最初にコンポーネントをレンダリングせずにonEnterを使うことができます。

解決策の1つは、onEnterメソッドの3番目のパラメータとしてコールバックを使用することです。あなたのケースでは

Here is a good thread that discusses how to use that functionality

それはその次の引数になりますように、それが見えます。あなたはそれを取って、認証チェックが解決したらそれを呼び出さなければなりません。

+0

また、反応ルータのどのバージョンを使用していますか? –

+0

あなたのお返事ありがとう@ ej-mason、私は反応ルータv3を使用しています。 また、スピナーを表示する別のコンポーネントにユーザーをリダイレクトするという考えは実行可能な解決策であり、私はそれが好きです。 私はHOCの内部でこのロジックをラップし、そこにスピナー/ローダーを表示しようとすることもできますが、ユーザーが認証されたことを示す後に_next_コールバックを呼び出すので、このプリロードasync sagaを使用してもコンポーネントの – Hawkes

+0

非同期イベントループの仕組みのために、次は、サガが実行される前に呼び出されています。非同期関数は、すべての同期コードが終了してから実行されるまで待機する必要があります。 –

関連する問題