Reduxストレージの状態をリセットするにはどうすればいいですか?

7038 ワード

How to reset the state of a Redux store?
I am using Redux for state management. Reduxを使用してステータス管理を行っています.How do I reset the store to its initial state? ショップを初期状態にリセットするにはどうすればいいですか?
For example, let's say I have two user accounts ( u1 and u2 ). たとえば、2つのユーザー・アカウント(u1u2)があるとします.Imagine the following sequence of events:次のイベント・シーケンスを想像します.
  • User u1 logs into the app and does something, so we cache some data in the store. ユーザu1は、アプリケーションにログインしてアクションを実行するため、ストレージにいくつかのデータをキャッシュします.
  • User u1 logs out. ユーザーu1はログアウトします.
  • User u2 logs into the app without refreshing the browser. ユーザーu2は、ブラウザをリフレッシュすることなくアプリケーションにログインします.

  • At this point, the cached data will be associated with u1 , and I would like to clean it up. このとき、キャッシュされたデータはu1に関連付けられ、クリーンアップしたいと思います.
    How can I reset the Redux store to its initial state when the first user logs out? 最初のユーザーがログアウトした場合、Reduxストレージを初期状態にリセットするにはどうすればいいですか?
    1階
    参照先:https://stackoom.com/question/2PT3s/Reduxストレージの状態をリセットする方法
    2階
    One way to do that would be to write a root reducer in your application. 1つの方法は、アプリケーションでルート削減器を作成することです.
    The root reducer would normally delegate handling the action to the reducer generated by combineReducers() . ルート減速機は、通常、combineReducers()によって生成された減速機に処理操作を委任する.However, whenever it receives USER_LOGOUT action, it returns the initial state all over again. しかし、USER_LOGOUT操作が受信されるたびに、それは再び初期状態に戻る.
    For example,if your root reducer looked like this:たとえば、ルート減速機が次のように表示されている場合:
    const rootReducer = combineReducers({
      /* your app’s top-level reducers */
    })
    

    You can rename it to appReducer and write a new rootReducer delegating to it:appReducerと名前を変更し、rootReducerに新しいライセンスを作成できます.
    const appReducer = combineReducers({
      /* your app’s top-level reducers */
    })
    
    const rootReducer = (state, action) => {
      return appReducer(state, action)
    }
    

    Now we just need to teach the new rootReducer to return the initial state after USER_LOGOUT action. 現在、rootReducerの動作後に新しいUSER_LOGOUTが初期状態に戻ることを教えるだけです.As we know, reducers are supposed to return the initial state when they are called with undefined as the first argument, no matter the action. 周知のように、reducerは、どの操作を使用しても、undefinedを第1のパラメータとして呼び出して初期状態に戻らなければならない.Let's use this fact to conditionally strip the accumulated state as we pass it to appReducer:この事実を利用して、累積stateappReducerappReducer累積stateに伝えましょう.
     const rootReducer = (state, action) => {
      if (action.type === 'USER_LOGOUT') {
        state = undefined
      }
    
      return appReducer(state, action)
    }
    

    Now, whenever USER_LOGOUT fires, all reducers will be initialized anew. USER_LOGOUTがトリガーされるたびに、すべてのreducerが再初期化されます.They can also return something different than they did initially if they want to because they can check action.type as well. もしよろしければ、action.typeもチェックできるので、最初とは違うものに戻ることもできます.
    To reiterate,the full new code looks like this:完全な新しいコードは以下の通りです.
    const appReducer = combineReducers({
      /* your app’s top-level reducers */
    })
    
    const rootReducer = (state, action) => {
      if (action.type === 'USER_LOGOUT') {
        state = undefined
      }
    
      return appReducer(state, action)
    }
    

    Note that I'm not mutating the state here, I am merely reassigning the reference of a local variable called state before passing it to another function. ここでは変異の状態はありませんが、ローカル変数と呼ばれるstateを参照して別の関数に渡す前に再割り当てするだけです.Mutating a state object would be a violation of Redux principles. ステータスオブジェクトを変更すると、Reduxの原則に違反します.
    In case you are using redux-persist , you may also need to clean your storage. redux-persistを使用する場合は、ストレージをクリーンアップする必要がある場合があります.Redux-persist keeps a copy of your state in a storage engine, and the state copy will be loaded from there on refresh. Redux-persistはステータスコピーをストレージエンジンに保存し、ステータスコピーはリフレッシュ時にロードされます.
    First, you need to import the appropriate storage engine and then, to parse the state before setting it to undefined and clean each storage state key. まず、適切なストレージエンジンをインポートし、ステータスを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);
    };
    

    #3階
    Simply have your logout link clear session and refresh the page. ログアウトリンクでセッションをクリアし、ページをリフレッシュするだけです.No additional code needed for your store. お店には他のコードは必要ありません.Any time you want to completely reset the state a page refresh is a simple and easily repeatable way to handle it. ステータスを完全にリセットするたびに、ページのリフレッシュは簡単で繰り返しやすい処理です.
    #4階
    I've created a component to give Redux the ability of resetting state, you just need to use this component to enhance your store and dispatch a specific action.type to trigger reset. Reduxにステータスをリセットする機能を付与するコンポーネントを作成しました.このコンポーネントを使用して、お店を強化し、特定のactionを割り当てるだけです.typeでリセットをトリガーします.The thought of implementation is same as what @Dan Abramov said. 実現の思想は@Dan Abramovが言ったのと同じである.
    Github: https://github.com/wwayne/redux-reset GitHub: https ://github.com/wwayne/redux-reset
    #5階
    I'd like to point out that the accepted comment by Dan Abramov is correct except we experienced a strange issue when using the react-router-redux package along with this approach. 私が指摘したいのは、ダン・アブラモフ(Dan Abramov)のコメントは正しいです.react-router-reduxパッケージをこの方法と一緒に使用する場合を除いて、私たちは奇妙な問題に遭遇しました.Our fix was to not set state to undefined but rather still use the current routing reducer.私たちの解決方法は、ステータスをundefinedに設定するのではなく、現在のルーティングを使用しています.プログラムを解く.So I would suggest implementing the solution below if you are using this packageですので、このパッケージを使用している場合は、次のソリューションを実施することをお勧めします.
    const rootReducer = (state, action) => {
      if (action.type === 'USER_LOGOUT') {
        const { routing } = state
        state = { routing } 
      }
      return appReducer(state, action)
    }
    

    #6階
    This approach is very right: Destruct any specific state "NAME"to ignore and keep others. この方法は正しい:任意の特定の状態「NAME」を破壊して他の状態を無視して保持する.
    const rootReducer = (state, action) => {
        if (action.type === 'USER_LOGOUT') {
            state.NAME = undefined
        }
        return appReducer(state, action)
    }