web-dev-qa-db-ja.com

初期状態のデフォルト値は、ストアがredux-persistで再水和する前にロードされます

アプリが redux-persist で起動した後、保存されたデータにアクセスできません。

レデューサーは、初期状態で定義されたデータで初期化されます。前のセッションの状態がAsyncStorageでロードされるまでに、コンポーネントはすでにデフォルトのデータで表示されています。

データが正常に保存およびフェッチされていることを知っています。画面を別の画面に置いて戻ってみると、データが正しく表示されていることがわかります。状態と小道具をデバッグすると、これが非同期タイミングの問題であることもわかります。

ストアが再水和した後まで、reduxコンテナのロードを遅らせるにはどうすればよいですか?または、ストアの読み込みが完了したときにコンテナ(およびその子)を強制的に更新して更新することはできますか?

これが私が試したことです。ストアを構成するには:

export default function configureStore(initialState) {
    const middlewares = [thunk];
    if (process.env.NODE_ENV === `development`) {
        const createLogger = require(`redux-logger`);
        const logger = createLogger();
        middlewares.Push(logger);
    }

    let store = compose(
        applyMiddleware(...middlewares),
        autoRehydrate() )(createStore)(reducers);

        persistStore(store, {blacklist: ['routing'], storage: AsyncStorage}, () => {
            store.dispatch(storeRehydrateComplete())
        })


    return store
}

これが他のすべてのコンポーネントを更新することを期待して(reduxのすべてのレデューサーがアクションで呼び出されるため)、ストアがロードを終了したときにトリガーされるアクションを作成しようとしました:

import { REHYDRATE_STORE } from './types'

export function storeRehydrateComplete(){
    return {
        type: REHYDRATE_STORE,
    }
}

そしてそれはレデューサーです:import {REHYDRATE_STORE} from '../ actions/types' const initialState = {storeIsReady:false}

export default function reducer(state = initialState, action){
    switch (action.type) {
        case REHYDRATE_STORE:
            return {...state, storeIsReady:true}
            break;
        default:
            return state
            break;
    }
}

しかし、再水和が完了するとstoreIsReadyの状態がtrueに変わりますが、コンテナーコンポーネントを強制的に更新する方法がわかりません。

16
amirfl

私はこのレシピに従ってそれを解決しました: delay-render-until-rehydration-complete

基本的に解決策は次のとおりです。
<Provider>をラップするコンポーネントで、ストアがまだ水分補給されているかどうかを追跡するローカル状態フラグを作成します。このフラグを更新するためにpersistStore()のコールバックを使用する。このラッパーのrender関数で、フラグがtrueの場合は、<Provider>をレンダリングします。それ以外の場合は、一時ビューをレンダリングします。

10
amirfl