アプリが 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に変わりますが、コンテナーコンポーネントを強制的に更新する方法がわかりません。
私はこのレシピに従ってそれを解決しました: delay-render-until-rehydration-complete
基本的に解決策は次のとおりです。<Provider>
をラップするコンポーネントで、ストアがまだ水分補給されているかどうかを追跡するローカル状態フラグを作成します。このフラグを更新するためにpersistStore()のコールバックを使用する。このラッパーのrender関数で、フラグがtrueの場合は、<Provider>
をレンダリングします。それ以外の場合は、一時ビューをレンダリングします。