Reduxストアの状態をリセットする方法は?


455

状態管理にReduxを使用しています。
ストアを初期状態にリセットするにはどうすればよいですか?

たとえば、2つのユーザーアカウント(u1u2)があるとします。
次の一連のイベントを想像してください。

  1. ユーザーu1がアプリにログインして何かを行うので、一部のデータをストアにキャッシュします。

  2. ユーザーがu1ログアウトします。

  3. ユーザーu2はブラウザを更新せずにアプリにログインします。

この時点で、キャッシュされたデータはに関連付けu1られます。クリーンアップしたいと思います。

最初のユーザーがログアウトしたときにReduxストアを初期状態にリセットするにはどうすればよいですか?


8
(セキュリティの観点から)ログアウト時に状態をクリアすることをお
勧めします

回答:


1033

これを行う1つの方法は、アプリケーションでルートリデューサーを記述することです。

ルートレデューサーは通常、アクションの処理をによって生成されたレデューサーに委任しcombineReducers()ます。ただし、USER_LOGOUTアクションを受け取るたびに、最初の状態を最初から返します。

たとえば、ルートリデューサーが次のようになっているとします。

const rootReducer = combineReducers({
  /* your app’s top-level reducers */
})

名前をに変更してappReducer、新しいrootReducer委任を書き込むことができます。

const appReducer = combineReducers({
  /* your app’s top-level reducers */
})

const rootReducer = (state, action) => {
  return appReducer(state, action)
}

これでrootReducerUSER_LOGOUTアクションの後に初期状態を返すように新しいものを教える必要があるだけです。ご存じのように、レデューサーはundefined、アクションに関係なく、最初の引数として呼び出されたときに初期状態を返すことになっています。この事実を使用して、次のstateように渡された累積を条件付きで削除しappReducerます。

 const rootReducer = (state, action) => {
  if (action.type === 'USER_LOGOUT') {
    state = undefined
  }

  return appReducer(state, action)
}

これで、USER_LOGOUT起動すると、すべてのレデューサーが新たに初期化されます。また、チェックaction.typeもできるため、必要に応じて、最初とは異なるものを返すこともできます。

繰り返しになりますが、完全な新しいコードは次のようになります。

const appReducer = combineReducers({
  /* your app’s top-level reducers */
})

const rootReducer = (state, action) => {
  if (action.type === 'USER_LOGOUT') {
    state = undefined
  }

  return appReducer(state, action)
}

ここでは状態を変更していないことに注意してください。別の関数に渡す前に呼び出されたローカル変数の参照再割り当てしているだけですstate。状態オブジェクトを変更すると、Reduxの原則に違反します。

redux-persistを使用している場合は、ストレージをクリーンアップする必要がある場合もあります。Redux-persistは状態のコピーをストレージエンジンに保存し、状態のコピーは更新時にそこから読み込まれます。

まず、適切なストレージエンジンをインポートしてから、状態を解析してから設定する前にundefined、各ストレージ状態キーをクリーンアップする必要があります。

const rootReducer = (state, action) => {
    if (action.type === SIGNOUT_REQUEST) {
        // for all keys defined in your persistConfig(s)
        storage.removeItem('persist:root')
        // storage.removeItem('persist:otherKey')

        state = undefined;
    }
    return appReducer(state, action);
};

15
私は好奇心旺盛なダンです、あなたもあなたの減速機でこのようなことをすることができますか CLEAR_DATAがアクションです。case 'CLEAR_DATA': return initialState
HussienK

6
@HussienKは機能しますが、すべてのレデューサーの状態ではありません。
Cory Danielson

12
ここでは、動的にあなたが非同期レデューサーを使用する場合の減速を組み合わせたバージョンがある:export const createRootReducer = asyncReducers => { const appReducer = combineReducers({ myReducer ...asyncReducers }); return (state, action) => { if (action.type === 'LOGOUT_USER') { state = undefined; } return appReducer(state, action); } };
イヴォSabev

2
if (action.type === 'RESET') return action.stateFromLocalStorage
Dan Abramov

3
このアプローチは状態とそのすべての歴史を完全にクリアしますか?セキュリティの観点から考えています。これが実装されている場合、USER_LOGOUTアクションが発生すると、以前から状態データを取得できますか?(例:devtools経由)
AlexKempton 2017

81

このアプローチでreact-router-reduxパッケージを使用しているときに奇妙な問題が発生したことを除いて、Dan Abramovの承認されたコメントが正しいことを指摘しておきます。私たちの修正は、状態をに設定せずundefined、現在のルーティングレデューサーを使用することでした。したがって、このパッケージを使用している場合は、以下のソリューションを実装することをお勧めします

const rootReducer = (state, action) => {
  if (action.type === 'USER_LOGOUT') {
    const { routing } = state
    state = { routing } 
  }
  return appReducer(state, action)
}

19
ここでの要点は、ログアウト時に状態ツリー全体をクリアしたくない場合があることだと思います。このアプローチは、任意のサブツリーのルートリデューサーでも同じように機能するため、この手法を次のように、ツリー全体のルートリデューサーでクリアしない「特別な」子を選択するのではなく、クリアたいサブツリー
davnicwil

1
私はあなたが今言及しているこの問題を経験していると思います(ログアウト時にルートが正しいパスに設定されますが、完全に異なるコンポーネントがロードされます)私はあなたに似たものを実装してそれを修正しましたが、不変のjsがこれを大量に処理しています。最終的に、RESET-STATEアクションを持つ親のレデューサーを作成しました。ルーティングにまったく触れないようにするために、そのレデューサーから継承しています
Neta Meta

同様の問題が発生していましたが、これで修正されました。ありがとう。
ロイドワトキン

3
react-redux-routerを使用する場合、プロパティはrouterあり、そうでないことに注意してくださいrounting
Mrchief

2
@MrchiefそれはcombineReducers()あなたがcombineReducers({routing: routingReducer})それをあなたがそれで定義したものに依存します.....もしそれが答えで説明されたようになったなら
ベン・ロンズデール

40

アクションを定義します。

const RESET_ACTION = {
  type: "RESET"
}

次に、各レデューサーで複数のアクションを使用switchまたはif-else処理することを想定して、各レデューサーで 私はケースを取り上げるつもりですswitch

const INITIAL_STATE = {
  loggedIn: true
}

const randomReducer = (state=INITIAL_STATE, action) {
  switch(action.type) {
    case 'SOME_ACTION_TYPE':

       //do something with it

    case "RESET":

      return INITIAL_STATE; //Always return the initial state

   default: 
      return state; 
  }
}

このようにしてRESET、アクションを呼び出すたびに、レデューサーはデフォルトの状態でストアを更新します。

これで、ログアウトのために次のように処理できます。

const logoutHandler = () => {
    store.dispatch(RESET_ACTION)
    // Also the custom logic like for the rest of the logout handler
}

ブラウザを更新せずに、ユーザーがログインするたび。ストアは常にデフォルトになります。

store.dispatch(RESET_ACTION)アイデアを詳しく説明します。あなたはおそらくその目的のためにアクションクリエーターを持っているでしょう。より良い方法は、あなたが持っていることですLOGOUT_ACTION

これを発送したらLOGOUT_ACTION。カスタムミドルウェアは、Redux-SagaまたはRedux-Thunkを使用して、このアクションを傍受できます。ただし、どちらの方法でも、別のアクション「RESET」をディスパッチできます。このようにして、ストアのログアウトとリセットは同期的に行われ、ストアは別のユーザーがログインできるようになります。


1
これはundefined他の答えで好きなように状態を設定するよりも良いアプローチだと思います。アプリケーションが状態ツリーを期待していて、undefined代わりにそれを与える場合、空のツリーだけではなく、対処する必要のあるバグと頭痛がたくさんあります。
2018

3
@worc未定義の状態を受け取ったときにレデューサーがinitialStateを返すため、状態は実際には未定義ではありません
Guillaume

3
@worcは、このアプローチでは、だれかが新しいレデューサーを作成するたびに、リセットケースを追加することを忘れないようにする必要があると考えています。
Francute、

1
これらの両方の理由と、RESET_ACTIONがアクションであるという考えから、私は間違いなくこれについて私の考えを変えました。ですから、そもそもレデューサーには属していません。
2018

1
これは間違いなく正しいアプローチです。状態を初期状態以外に設定すると、問題が発生するだけです
Sebastian Serrano

15

ベストアンサーに対する簡単な答え:

const rootReducer = combineReducers({
    auth: authReducer,
    ...formReducers,
    routing
});


export default (state, action) =>
  rootReducer(action.type === 'USER_LOGOUT' ? undefined : state, action);

これはうまくいきました。私はダンの答えから来ましたが、理解できません。
アルジョンヤマロ

14
 const reducer = (state = initialState, { type, payload }) => {

   switch (type) {
      case RESET_STORE: {
        state = initialState
      }
        break
   }

   return state
 }

すべてまたは一部のレデューサーによって処理される、初期ストアにリセットするアクションを起動することもできます。1つのアクションで、状態全体、または自分に合っていると思われるその一部へのリセットをトリガーできます。これは、これを行う最も簡単で制御可能な方法であると私は信じています。


10

Reduxでは、次のソリューションを適用した場合、すべてのレデューサー(例:{user:{name、email}})にinitialStateが設定されていると想定しています。多くのコンポーネントでこれらのネストされたプロパティをチェックするため、この修正により、レンダリングプロパティが結合プロパティの条件で壊れないようにします(たとえば、state.user.emailがエラーをスローする場合、上記のソリューションでは未定義です)。

const appReducer = combineReducers({
  tabs,
  user
})

const initialState = appReducer({}, {})

const rootReducer = (state, action) => {
  if (action.type === 'LOG_OUT') {
    state = initialState
  }

  return appReducer(state, action)
}

7

NGRX4の更新

NGRX 4に移行する場合、移行ガイドから、リデューサーを組み合わせるためのrootreducerメソッドがActionReducerMapメソッドに置き換えられていることに気付いたかもしれません。最初は、この新しい方法で状態をリセットするのは難しいかもしれません。実際には簡単ですが、これを行う方法が変更されました。

このソリューションは、NGRX4 Githubドキュメントのメタリデューサー APIセクションに触発されています

まず、NGRXの新しいActionReducerMapオプションを使用して、このようにリデューサーを組み合わせているとします。

//index.reducer.ts
export const reducers: ActionReducerMap<State> = {
    auth: fromAuth.reducer,
    layout: fromLayout.reducer,
    users: fromUsers.reducer,
    networks: fromNetworks.reducer,
    routingDisplay: fromRoutingDisplay.reducer,
    routing: fromRouting.reducer,
    routes: fromRoutes.reducer,
    routesFilter: fromRoutesFilter.reducer,
    params: fromParams.reducer
}

ここで、app.module内から状態をリセットしたいとします `

//app.module.ts
import { IndexReducer } from './index.reducer';
import { StoreModule, ActionReducer, MetaReducer } from '@ngrx/store';
...
export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
    return function(state, action) {

      switch (action.type) {
          case fromAuth.LOGOUT:
            console.log("logout action");
            state = undefined;
      }

      return reducer(state, action);
    }
  }

  export const metaReducers: MetaReducer<any>[] = [debug];

  @NgModule({
    imports: [
        ...
        StoreModule.forRoot(reducers, { metaReducers}),
        ...
    ]
})

export class AppModule { }

`

そして、それは基本的にNGRX 4で同じ効果を達成する1つの方法です。


5

ダン、ライアン、ロブのアプローチを組み合わせて、router状態を維持し、状態ツリー内の他のすべてを初期化することを説明するために、私はこれで終わりました:

const rootReducer = (state, action) => appReducer(action.type === LOGOUT ? {
    ...appReducer({}, {}),
    router: state && state.router || {}
  } : state, action);

4

Reduxに状態をリセットできるようにするコンポーネントを作成しました。このコンポーネントを使用してストアを拡張し、特定のaction.typeをディスパッチしてリセットをトリガーするだけです。実装の考え方は、@ Dan Abramovが言ったことと同じです。

Github:https : //github.com/wwayne/redux-reset


4

状態をクリアするアクションを作成しました。したがって、ログアウトアクションクリエーターをディスパッチすると、状態をクリアするアクションもディスパッチします。

ユーザーレコードアクション

export const clearUserRecord = () => ({
  type: CLEAR_USER_RECORD
});

ログアウトアクションの作成者

export const logoutUser = () => {
  return dispatch => {
    dispatch(requestLogout())
    dispatch(receiveLogout())
    localStorage.removeItem('auth_token')
    dispatch({ type: 'CLEAR_USER_RECORD' })
  }
};

減力剤

const userRecords = (state = {isFetching: false,
  userRecord: [], message: ''}, action) => {
  switch (action.type) {
    case REQUEST_USER_RECORD:
    return { ...state,
      isFetching: true}
    case RECEIVE_USER_RECORD:
    return { ...state,
      isFetching: false,
      userRecord: action.user_record}
    case USER_RECORD_ERROR:
    return { ...state,
      isFetching: false,
      message: action.message}
    case CLEAR_USER_RECORD:
    return {...state,
      isFetching: false,
      message: '',
      userRecord: []}
    default:
      return state
  }
};

これが最適かどうかわかりませんか?


2

redux-actionsを使用している場合は、HOF(高次関数)を使用した簡単な回避策を次に示しhandleActionsます。

import { handleActions } from 'redux-actions';

export function handleActionsEx(reducer, initialState) {
  const enhancedReducer = {
    ...reducer,
    RESET: () => initialState
  };
  return handleActions(enhancedReducer, initialState);
}

そして、handleActionsEx元の代わりにを使用してhandleActionsレデューサーを処理します。

ダンの答えはこの問題について素晴らしい考えを与えますが、私はを使用しているため、私にはうまくいきませんでしたredux-persist
とともに使用した場合redux-persist、単にundefined状態を渡すだけでは永続的な動作がトリガーされなかったため、アイテムをストレージから手動で削除する必要があることがわかっていました(この場合は、React Native AsyncStorage)。

await AsyncStorage.removeItem('persist:root');

または

await persistor.flush(); // or await persistor.purge();

私にも効かなかった-彼らは私に怒鳴った (たとえば、「予期しないキー_persist ...」のように不平を言う)

次に、RESETアクションタイプに遭遇したときに、すべての個々のレデューサーが独自の初期状態を返すようにしたいだけです。このように、永続化は自然に処理されます。明らかに上記のユーティリティ関数(handleActionsEx)がないと、私のコードはDRYには見えませんが(たった1つのライナー、つまりRESET: () => initialState)、それは我慢できませんでした。


2

次の解決策は私のために働いた。

メタリデューサーに状態のリセット機能を追加しました。

return reducer(undefined, action);

すべてのレデューサーを初期状態に設定します。undefined代わりに戻ると、ストアの構造が破壊されたためにエラーが発生していました。

/reducers/index.ts

export function resetState(reducer: ActionReducer<State>): ActionReducer<State> {
  return function (state: State, action: Action): State {

    switch (action.type) {
      case AuthActionTypes.Logout: {
        return reducer(undefined, action);
      }
      default: {
        return reducer(state, action);
      }
    }
  };
}

export const metaReducers: MetaReducer<State>[] = [ resetState ];

app.module.ts

import { StoreModule } from '@ngrx/store';
import { metaReducers, reducers } from './reducers';

@NgModule({
  imports: [
    StoreModule.forRoot(reducers, { metaReducers })
  ]
})
export class AppModule {}

2

セキュリティの観点から、ユーザーをログアウト時に行うための最も安全な方法は、すべての永続状態をリセットすることです(例:クッキー、localStorageIndexedDBWeb SQL、など)と使用して、ページのハードリフレッシュを行いますwindow.location.reload()。ずさんな開発者が偶然または意図的に一部の機密データをwindowDOMなどに保存した可能性があります。すべての永続的な状態を吹き飛ばしてブラウザを更新することが、前のユーザーからの情報が次のユーザーに漏洩しないことを保証する唯一の方法です。

(もちろん、共有コンピューターのユーザーは「プライベートブラウジング」モードを使用し、ブラウザーウィンドウを自分で閉じ、「ブラウジングデータを消去」機能を使用する必要がありますが、開発者として、誰もが常にそうであるとは期待できませんその勤勉な)


1
なぜ人々はこれに反対票を投じたのですか?空のコンテンツで新しいredux状態を実行すると、基本的に以前の状態がメモリに残り、理論的にはそれらのデータにアクセスできます。ブラウザを更新するのが最も安全です。
Wilhelm Sorban、2018

2

ダンの答えの上に構築されたtypescriptで作業するときの私の回避策(reduxのタイピングではundefined、最初の引数としてレデューサーに渡すことができないため、定数に初期ルート状態をキャッシュします):

// store

export const store: Store<IStoreState> = createStore(
  rootReducer,
  storeEnhacer,
)

export const initialRootState = {
  ...store.getState(),
}

// root reducer

const appReducer = combineReducers<IStoreState>(reducers)

export const rootReducer = (state: IStoreState, action: IAction<any>) => {
  if (action.type === "USER_LOGOUT") {
    return appReducer(initialRootState, action)
  }

  return appReducer(state, action)
}


// auth service

class Auth {
  ...

  logout() {
    store.dispatch({type: "USER_LOGOUT"})
  }
}

2

受け入れられた答えは私のケースを解決するのに役立ちました。しかし、私は、すべてではない状態をクリアする必要がある場合に遭遇しました。だから-私はこのようにしました:

const combinedReducer = combineReducers({
    // my reducers 
});

const rootReducer = (state, action) => {
    if (action.type === RESET_REDUX_STATE) {
        // clear everything but keep the stuff we want to be preserved ..
        delete state.something;
        delete state.anotherThing;
    }
    return combinedReducer(state, action);
}

export default rootReducer;

これが他の誰かを助けることを願っています:)


10を超える状態があるが、1つのレデューサーのみの状態をリセットしたい場合はどうなりますか?
ポール

1

@ dan-abramovの回答の単なる拡張であり、特定のキーをリセットしないようにする必要がある場合があります。

const retainKeys = ['appConfig'];

const rootReducer = (state, action) => {
  if (action.type === 'LOGOUT_USER_SUCCESS' && state) {
    state = !isEmpty(retainKeys) ? pick(state, retainKeys) : undefined;
  }

  return appReducer(state, action);
};

1

私にとってうまくいった迅速かつ簡単なオプションは、redux-resetを使用することでした。これは簡単で、より大きなアプリ向けのいくつかの高度なオプションもあります。

ストア作成でのセットアップ

import reduxReset from 'redux-reset'
...
const enHanceCreateStore = compose(
applyMiddleware(...),
reduxReset()  // Will use 'RESET' as default action.type to trigger reset
)(createStore)
const store = enHanceCreateStore(reducers)

ログアウト関数で「リセット」をディスパッチします

store.dispatch({
type: 'RESET'
})

お役に立てれば


1

Reduxが初期状態の同じ変数を参照しないようにするための私の考え:

// write the default state as a function
const defaultOptionsState = () => ({
  option1: '',
  option2: 42,
});

const initialState = {
  options: defaultOptionsState() // invoke it in your initial state
};

export default (state = initialState, action) => {

  switch (action.type) {

    case RESET_OPTIONS:
    return {
      ...state,
      options: defaultOptionsState() // invoke the default function to reset this part of the state
    };

    default:
    return state;
  }
};

デフォルトの状態を関数として記述するという考えは、実際にその日を救いました。🙏ありがとう
クリス・ポール

0

このアプローチは非常に適切です。特定の状態「NAME」を破棄して、他の状態を無視して保持します。

const rootReducer = (state, action) => {
    if (action.type === 'USER_LOGOUT') {
        state.NAME = undefined
    }
    return appReducer(state, action)
}

状態ツリーの一部のみをリセットする必要がある場合はUSER_LOGOUT、そのレデューサーをリッスンしてそこで処理することもできます。
Andy_D 2016

0

なぜあなただ​​けを使用しないのですかreturn module.exports.default();)

export default (state = {pending: false, error: null}, action = {}) => {
    switch (action.type) {
        case "RESET_POST":
            return module.exports.default();
        case "SEND_POST_PENDING":
            return {...state, pending: true, error: null};
        // ....
    }
    return state;
}

注:アクションのデフォルト値をに設定していることを確認してください{}。switch action.typeステートメント内をチェックするときにエラーが発生しないようにしてください。


0

受け入れられた回答はうまく機能していることがわかりno-param-reassignましたが、ESLint エラーが発生しました-https : //eslint.org/docs/rules/no-param-reassign

代わりに、これを処理して、状態のコピーを作成する方法を以下に示します(私の理解では、Reduxyがやるべきことです...):

import { combineReducers } from "redux"
import { routerReducer } from "react-router-redux"
import ws from "reducers/ws"
import session from "reducers/session"
import app from "reducers/app"

const appReducer = combineReducers({
    "routing": routerReducer,
    ws,
    session,
    app
})

export default (state, action) => {
    const stateCopy = action.type === "LOGOUT" ? undefined : { ...state }
    return appReducer(stateCopy, action)
}

しかし、状態のコピーを作成して、そのコピーを作成する別のレデューサー関数に渡すだけで、少し複雑すぎるのではないでしょうか。これはうまく読めませんが、より的確です:

export default (state, action) => {
    return appReducer(action.type === "LOGOUT" ? undefined : state, action)
}

0

Dan Abramovの答えに加えて、state = undefinedと一緒にaction = {type: '@@ INIT'}として明示的にactionを設定すべきではありません。上記のアクションタイプでは、すべてのレデューサーが初期状態を返します。


0

サーバーでは、変数iを持っている:global.isSsr =真 及び各減速で、私はconstのを持っている:初期状態は、 ストア内のデータをリセットするには、私はそれぞれのリデューサーで次の操作を行います appReducer.jsとの例

 const initialState = {
    auth: {},
    theme: {},
    sidebar: {},
    lsFanpage: {},
    lsChatApp: {},
    appSelected: {},
};

export default function (state = initialState, action) {
    if (typeof isSsr!=="undefined" && isSsr) { //<== using global.isSsr = true
        state = {...initialState};//<= important "will reset the data every time there is a request from the client to the server"
    }
    switch (action.type) {
        //...other code case here
        default: {
            return state;
        }
    }
}

最後にサーバーのルーターで:

router.get('*', (req, res) => {
        store.dispatch({type:'reset-all-blabla'});//<= unlike any action.type // i use Math.random()
        // code ....render ssr here
});

0

次の解決策は私のために働きます。

最初に開始我々のアプリケーションの減速状態があり、新鮮かつ新しいデフォルトで初期状態

APPの初期ロードを呼び出してデフォルトの状態を維持するアクションを追加する必要があります

アプリケーションからログアウトしながら、私たちは簡単なことができます再割り当てするには、デフォルトの状態と減速は同じように動作します新しいです

メインAPPコンテナー

  componentDidMount() {   
    this.props.persistReducerState();
  }

メインAPPレデューサー

const appReducer = combineReducers({
  user: userStatusReducer,     
  analysis: analysisReducer,
  incentives: incentivesReducer
});

let defaultState = null;
export default (state, action) => {
  switch (action.type) {
    case appActions.ON_APP_LOAD:
      defaultState = defaultState || state;
      break;
    case userLoginActions.USER_LOGOUT:
      state = defaultState;
      return state;
    default:
      break;
  }
  return appReducer(state, action);
};

状態をリセットするためのログアウト呼び出しアクション

function* logoutUser(action) {
  try {
    const response = yield call(UserLoginService.logout);
    yield put(LoginActions.logoutSuccess());
  } catch (error) {
    toast.error(error.message, {
      position: toast.POSITION.TOP_RIGHT
    });
  }
}

これで問題が解決することを願っています!


0

状態を初期状態にリセットするために、次のコードを記述しました。

const appReducers = (state, action) =>
   combineReducers({ reducer1, reducer2, user })(
     action.type === "LOGOUT" ? undefined : state,
     action
);

0

受け入れられた回答の解決策ではできないことの1つは、パラメーター化されたセレクターのキャッシュをクリアすることです。このようなセレクターがある場合:

export const selectCounter1 = (state: State) => state.counter1;
export const selectCounter2 = (state: State) => state.counter2;
export const selectTotal = createSelector(
  selectCounter1,
  selectCounter2,
  (counter1, counter2) => counter1 + counter2
);

次に、次のようにログアウト時にそれらを解放する必要があります。

selectTotal.release();

それ以外の場合、セレクターの最後の呼び出しのメモ化された値と最後のパラメーターの値は引き続きメモリーに残ります。

コードサンプルはngrx docsからです。


0

私にとって最もうまくいったのはのinitialState代わりにを設定することですstate

  const reducer = createReducer(initialState,
  on(proofActions.cleanAdditionalInsuredState, (state, action) => ({
    ...initialState
  })),

-1

別のオプションは次のとおりです。

store.dispatch({type: '@@redux/INIT'})

'@@redux/INIT'はreduxがのときに自動的にディスパッチするアクションタイプですcreateStore。したがって、すべてのレデューサーに既にデフォルトがあると仮定すると、これはそれらにキャッチされ、状態を新たに開始します。ただし、これはreduxのプライベート実装の詳細と見なされる可能性があるため、購入者は注意してください...


状態が変化しないことを確認しました。ReduxDevtoolsに最初のアクションとして示されている@@ INITも試しました
Reza

-2

ログアウトリンクをクリアして、ページを更新してください。ストアに追加のコードは必要ありません。状態を完全にリセットしたいときはいつでも、ページの更新はそれを処理するためのシンプルで簡単に繰り返し可能な方法です。


1
ストアをローカルストレージに同期するミドルウェアを使用している場合はどうなりますか?その後、あなたのアプローチはまったく機能しません...
Spock

8
なぜ人々がこのような答えに反対票を投じるのか、私にはよくわかりません。
ウィリアムジャッド2018

なぜ人々はこれに反対票を投じたのですか?空のコンテンツで新しいredux状態を実行すると、基本的に以前の状態がメモリに残り、理論的にはそれらのデータにアクセスできます。ブラウザを更新するのが最も安全です。
Wilhelm Sorban

-3

onLogout() {
  this.props.history.push('/login'); // send user to login page
  window.location.reload(); // refresh the page
}


説明する?@SinanSamet
Nikita Beznosikov

明確にするために、私はこれに反対票を投じませんでした。しかし、私はそれを思いとどまらせます。ログインしてリロードする場合は、おそらくログアウトします。しかし、あなたがあなたの状態を失ったからです。redux-persistを使用しない限り、ログアウトすることもできません。全体として、私は次のような機能を見るのが嫌いですwindow.location.reload();
Sinan Samet

-このような関数を記述しないでください。- なぜ?-嫌いです。
Nikita Beznosikov

1
ページの再読み込みは、ストア状態のリセットとは異なります。その上、あなたはのない環境にいるかもしれませんwindow。例えば、反応ネイティブ
Max
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.