একটি রেডাক্স স্টোরের অবস্থা কীভাবে পুনরায় সেট করবেন?


455

আমি রাষ্ট্র পরিচালনার জন্য রেডাক্স ব্যবহার করছি।
আমি কীভাবে দোকানটির প্রাথমিক অবস্থায় পুনরায় সেট করব?

উদাহরণস্বরূপ, ধরা যাক আমার দুটি ব্যবহারকারীর অ্যাকাউন্ট রয়েছে ( u1এবং u2)।
ইভেন্টগুলির নিম্নলিখিত ক্রমটি কল্পনা করুন:

  1. ব্যবহারকারী u1অ্যাপ্লিকেশনটিতে লগইন করে এবং কিছু করে, তাই আমরা দোকানে কিছু ডেটা ক্যাশে করি।

  2. ব্যবহারকারী u1লগ আউট।

  3. ব্যবহারকারী u2ব্রাউজারটি রিফ্রেশ না করে অ্যাপে লগইন করে।

এই মুহুর্তে, ক্যাশেড ডেটা যুক্ত হবে u1এবং আমি এটি পরিষ্কার করতে চাই।

প্রথম ব্যবহারকারী লগ আউট করার সময় আমি কীভাবে রেডাক্স স্টোরটিকে তার প্রাথমিক অবস্থায় পুনরায় সেট করতে পারি?


8
পরিবর্তে (সুরক্ষা দৃষ্টিকোণ থেকে)
লগআউটে

উত্তর:


1033

এটি করার একটি উপায় হ'ল আপনার অ্যাপ্লিকেশনটিতে একটি রুট রিডুসার লিখুন।

রুট রিডিউসারটি সাধারণত উত্পাদিত হ্রাসকারীর কাছে ক্রিয়া পরিচালনা করার জন্য প্রতিনিধিত্ব করবে 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)
}

এখন আমাদের কেবল rootReducerনতুনটিকে USER_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। কোনও রাষ্ট্রের বস্তুকে রূপান্তর করা রেডাক্স নীতির লঙ্ঘন হবে।

আপনি যদি রিডেক্স-কন্টিনিস্ট ব্যবহার করছেন তবে আপনার স্টোরেজও পরিষ্কার করার দরকার হতে পারে। রেডাক্স-কন্টিনিস্ট স্টোরেজ ইঞ্জিনে আপনার রাজ্যের অনুলিপি রাখে এবং রাষ্ট্রীয় অনুলিপিটি সেখান থেকে লোড হয়ে যায় রিফ্রেশের সময়।

প্রথমে আপনাকে যথাযথ স্টোরেজ ইঞ্জিনটি আমদানি করতে হবে এবং তারপরে, 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
হুসিয়েনকে

6
@ হাসিয়েনেক যা প্রতিটি হ্রাসকারীর জন্য রাজ্যে কাজ করবে না তা কার্যকর করবে।
কোরি ড্যানিয়েলসন

12
এখানে এমন একটি সংস্করণ রয়েছে যেখানে আপনি export const createRootReducer = asyncReducers => { const appReducer = combineReducers({ myReducer ...asyncReducers }); return (state, action) => { if (action.type === 'LOGOUT_USER') { state = undefined; } return appReducer(state, action); } };
অ্যাসিঙ্ক হ্রাসকারীদের

2
if (action.type === 'RESET') return action.stateFromLocalStorage
ড্যান আব্রামভ

3
এই পদ্ধতিটি কি রাষ্ট্র এবং এর সমস্ত ইতিহাস পুরোপুরি সাফ করে? আমি সুরক্ষা দৃষ্টিকোণ থেকে ভাবছি: যদি এটি প্রয়োগ করা হয়, একবার USER_LOGOUTপদক্ষেপটি সরিয়ে দেওয়া হয়, তবে কি পূর্বের থেকে রাষ্ট্রীয় ডেটা প্রাপ্ত করা সম্ভব? (যেমন
দেবতুলদের

81

আমি উল্লেখ করতে চাই যে ড্যান আব্রামভের গৃহীত মন্তব্যটি সঠিক, যদি না আমরা এই পদ্ধতির সাথে রিঅ্যাক্ট-রাউটার-রিডেক্স প্যাকেজটি ব্যবহার করার সময় একটি অদ্ভুত সমস্যাটি অনুভব করি। আমাদের undefinedফিক্সটি স্থিতি স্থাপন না করে বরং বর্তমান রাউটিং রিডিউসারটি ব্যবহার করা ছিল। আপনি নীচের সমাধানটি বাস্তবায়নের পরামর্শ দিচ্ছি যদি আপনি এই প্যাকেজটি ব্যবহার করছেন

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

19
আমি মনে করি এখানকার অবতরণীকরণটি হ'ল আপনি লগআউটে পুরো রাজ্য গাছটি সাফ করতে চাইবেন না - পদ্ধতির কোনও subtree এর রুট রিডুসারে সমানভাবে কাজ করে, এবং তাই কেবলমাত্র এর মূল হ্রাসকারীগুলিতে এই কৌশলটি প্রয়োগ করা আরও পরিষ্কার হতে পারে সাবট্রি (গুলি) আপনি পরিষ্কার করতে চান না, বরং ' গাছপালার' পুরো গাছের রুট
রিডিউসার

1
আমি মনে করি আপনি এখনই উল্লেখ করছেন এমন সমস্যাগুলি আমি অনুভব করছি, (যেখানে লগআউট করার সময় এটি রুটটি সঠিক পথে নির্ধারণ করবে তবে একটি সম্পূর্ণ ভিন্ন উপাদান লোড করবে) আমি এটি ঠিক করার জন্য আপনার অনুরূপ কিছু বাস্তবায়ন করেছি, তবে আমি মনে করি এর সাথে কিছু রয়েছে অপরিবর্তনীয় জেএস এটি ভর করছে। রিসেট-স্টেট অ্যাকশন রয়েছে এমন একটি প্যারেন্ট রিডুসার তৈরি করে আমি শেষ করেছি এবং সম্পূর্ণরূপে স্পর্শের রাউটিং এড়াতে আমি সেই রিডুসার থেকে উত্তরাধিকারী হয়েছি
নেতা মেটা

অনুরূপ সমস্যাগুলির সম্মুখীন হচ্ছিল, এটি এটি স্থির করেছে। ধন্যবাদ।
লয়েড ওয়াটকিন

3
মনে রাখবেন যে routerrounting
বিক্রিয়া

2
@ মরিচ এটি আপনার combineReducers()..... এর মতো সংজ্ঞায়িত করে তা নির্ভর করে ..... আপনার যদি combineReducers({routing: routingReducer})উত্তরটি বর্ণিত হয়েছে তবে এটি হবে
বেন লোনসডেল

39

একটি ক্রিয়া সংজ্ঞায়িত করুন:

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। একটি কাস্টম মিডলওয়্যার রেডাক্স-সাগা বা রেডাক্স-থঙ্কের সাহায্যে এই ক্রিয়াটি আটকাতে পারে। উভয় উপায়েই, আপনি অন্য ক্রিয়া 'রিসেট' প্রেরণ করতে পারেন। এই ভাবে স্টোর লগআউট এবং পুনরায় সেটটি সিঙ্ক্রোনজির সাথে ঘটবে এবং আপনার স্টোর অন্য ব্যবহারকারী লগইনের জন্য প্রস্তুত হবে will


1
আমি মনে করি undefinedএটি অন্য উত্তরের মতো কেবল স্থিতি স্থিতির চেয়ে ভাল পদ্ধতির । যখন আপনার অ্যাপ্লিকেশনটি কোনও রাষ্ট্র গাছের প্রত্যাশা করছে এবং আপনি তার undefinedপরিবর্তে এটি দেবেন তখন খালি গাছের চেয়ে আরও কিছু বাগ এবং মাথাব্যথা রয়েছে।
worc

3
@worc রাষ্ট্র আসলে undefined হবে না কারণ reducers initialState আসতে যখন তারা অনির্ধারিত রাষ্ট্র গ্রহণ
Guillaume,

3
@ ওয়ার্ক মনে করেন যে এই পদ্ধতির সাহায্যে প্রতিবার কেউ নতুন রিডুসার তৈরি করলে আপনাকে রিসেটের কেসটি যুক্ত করতে মনে রাখতে হবে।
ফ্রুটসুট

1
আমি অবশ্যই এই দুটি কারণেই এই বিষয়ে আমার মন পরিবর্তন করেছি এবং আরও মনে করি যে কোনও RESET_ACTION একটি ক্রিয়া । সুতরাং এটি আরম্ভ করার জন্য সত্যিকারের অন্তর্ভুক্ত নয়।
worc

1
এটি অবশ্যই সঠিক পন্থা। রাষ্ট্রকে আরম্ভ করা ছাড়া আরম্ভের রাষ্ট্রটি কেবল সমস্যার জন্য জিজ্ঞাসা করছে
সেবাস্তিয়ান সেরানানো

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
 }

আপনি প্রাথমিক স্টোরটিতে পুনরায় সেট করতে চান এমন কোনও বা সমস্ত হ্রাসকারীদের দ্বারা পরিচালিত কোনও ক্রিয়াকলাপও আপনি গুলি ছুড়তে পারেন। একটি ক্রিয়া আপনার পুরো রাজ্যে একটি রিসেট ট্রিগার করতে পারে, বা এটির কেবলমাত্র একটি অংশ যা আপনার উপযুক্ত মনে হয়। আমি বিশ্বাস করি এটি এটি করার সবচেয়ে সহজ এবং নিয়ন্ত্রণযোগ্য উপায়।


10

রেডাক্সের সাথে যদি নিম্নলিখিত সমাধানটি প্রয়োগ করে থাকে, যা ধরে নিয়েছে যে আমি আমার সমস্ত হ্রাসকারীদের (যেমন {ব্যবহারকারী: {নাম, ইমেল}}) একটি প্রাথমিক স্টেট সেট করেছি। অনেকগুলি উপাদানগুলিতে আমি এই নেস্টেড বৈশিষ্ট্যগুলি পরীক্ষা করে দেখি, তাই এই সংশোধন করে আমি আমার রেন্ডারগুলির পদ্ধতিগুলি সংযুক্ত সম্পত্তি শর্তে ভাঙা রোধ করি (যেমন, 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

আপডেট করুন এনজিআরএক্স 4

আপনি যদি এনজিআরএক্স 4 এ স্থানান্তরিত হন, আপনি মাইগ্রেশন গাইড থেকে লক্ষ্য করেছেন যে আপনার হ্রাসকারীদের একত্রিত করার জন্য রুট্রেডুসার পদ্ধতিটি অ্যাকশনরেদসার ম্যাপ পদ্ধতিতে প্রতিস্থাপন করা হয়েছে। প্রথমে, জিনিসগুলি করার এই নতুন পদ্ধতিটি পুনরায় সেট করা রাষ্ট্রকে একটি চ্যালেঞ্জ করে তুলতে পারে। এটি আসলে সরাসরি-এগিয়ে, তবুও এটি করার পদ্ধতি পরিবর্তিত হয়েছে।

এই সমাধানটি এনজিআরএক্স 4 গিথুব ডক্সের মেটা- হ্রাসকারী এপিআই বিভাগ দ্বারা অনুপ্রাণিত

প্রথমে বলি যে আপনি এনজিআরএক্স এর নতুন অ্যাকশনরেডুসারম্যাপ বিকল্পটি ব্যবহার করে আপনার হ্রাসকারীকে এই জাতীয়ভাবে সংযুক্ত করছেন:

//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
}

এখন, আসুন আপনি অ্যাপ.মডিউল within এর মধ্যে থেকে রাষ্ট্রটি পুনরায় সেট করতে চান তা বলুন `

//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 { }

`

এবং এটি এনজিআরএক্স 4 এর সাথে একই প্রভাব অর্জনের মূলত এক উপায়।


5

ড্যান, রায়ান এবং রব এর পদ্ধতির সাথে একত্রিত হয়ে, routerরাজ্য রক্ষার জন্য এবং রাষ্ট্রীয় গাছের সমস্ত কিছুর সূচনা করার জন্য , আমি এটি দিয়ে শেষ করেছি:

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

4

আমি রেডাক্সকে পুনরায় সেট করার ক্ষমতা দেওয়ার জন্য একটি উপাদান তৈরি করেছি, আপনার স্টোরটি বাড়ানোর জন্য আপনাকে কেবল এই উপাদানটি ব্যবহার করতে হবে এবং পুনরায় সেট করতে ট্রিগার করতে একটি নির্দিষ্ট ক্রিয়াকলাপ প্রেরণ করতে হবে। @ ড্যান আব্রামভ যা বলেছিলেন তা বাস্তবায়নের চিন্তাধারার মতোই।

গিথুব: 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

আপনি যদি রিডেক্স-অ্যাকশন ব্যবহার করছেন তবে এর জন্য একটি এইচএফ ( উচ্চতর ক্রম ফাংশন ) ব্যবহার করে একটি দ্রুত কর্মক্ষেত্র রয়েছে 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অবস্থা স্থিতিশীল আচরণকে ট্রিগার করে না, তাই আমি জানতাম যে আমাকে নিজেই স্টোরেজ থেকে আইটেমটি সরিয়ে ফেলতে হবে (এইভাবে আমার ক্ষেত্রে নেটিভ প্রতিক্রিয়া করুন AsyncStorage)।

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

অথবা

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

আমার পক্ষেও কাজ করেনি - তারা কেবল আমার দিকে চিত্কার করে। (উদাহরণস্বরূপ, "অপ্রত্যাশিত কী _ ব্যক্তি ..." এর মতো অভিযোগ করা )

তারপরে আমি হঠাৎ আমার সমস্ত চিন্তা-ভাবনাটি হ'ল কেবলমাত্র RESETক্রিয়াকলাপের মুখোমুখি হওয়ার সময় প্রতিটি পৃথক রিডুসারকে তাদের নিজস্ব প্রাথমিক অবস্থা ফিরিয়ে আনতে হবে । এইভাবে, অধ্যবসায় প্রাকৃতিকভাবে পরিচালনা করা হয়। স্পষ্টতই উপরের ইউটিলিটি ফাংশন ছাড়াই ( handleActionsEx), আমার কোডটি ডিআরওয়াই লাগবে না (যদিও এটি কেবল একটি লাইনার, অর্থাত্ RESET: () => initialState), তবে আমি এটি দাঁড়াতে পারলাম না 'আমি রূপান্তরকাজ পছন্দ করি c


2

নিম্নলিখিত সমাধানটি আমার পক্ষে কাজ করেছিল।

আমি মেটা হ্রাসকারীগুলিতে স্থিতি ফাংশনটি পুনরায় সেট করেছি key কীটি ব্যবহার করা হয়েছিল

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

একটি নিরাপত্তা দৃষ্টিকোণ থেকে, সবচেয়ে নিরাপদ জিনিস যখন একজন ব্যবহারকারী লগ আউট সমস্ত অবিরত রাষ্ট্র পুনরায় সেট করতে কি (উদা কুকিজ, এর localStorage, IndexedDB, Web SQL, ইত্যাদি) এবং ব্যবহার পৃষ্ঠার একটি হার্ড রিফ্রেশ না window.location.reload()। কোনও আড়ম্বরপূর্ণ বিকাশকারী দুর্ঘটনাক্রমে বা ইচ্ছাকৃতভাবে windowডিওএম ইত্যাদিতে কিছু সংবেদনশীল ডেটা সংরক্ষণ করে রাখা সম্ভব all

(অবশ্যই, একটি ভাগ করা কম্পিউটারে ব্যবহারকারী হিসাবে আপনার "ব্যক্তিগত ব্রাউজিং" মোড ব্যবহার করা উচিত, ব্রাউজার উইন্ডোটি নিজেই বন্ধ করা উচিত, "পরিষ্কার ব্রাউজিং ডেটা" ফাংশন ইত্যাদি ব্যবহার করা উচিত, তবে একজন বিকাশকারী হিসাবে আমরা আশা করতে পারি না যে সর্বদা সর্বদা থাকবে) পরিশ্রমী)


1
লোকেরা কেন এটিকে অবমূল্যায়ন করেছে? আপনি যখন খালি বিষয়বস্তু সহ একটি নতুন রিডেক্স রাজ্য করেন, তখন মূলত আপনার এখনও মেমরির পূর্ববর্তী রাজ্য থাকে এবং আপনি তাত্ত্বিকভাবে সেগুলি থেকে ডেটা অ্যাক্সেস করতে পারেন। ব্রাউজারকে রিফ্রেশ করা আপনার নিরাপদ বাজি!
উইলহেম সোর্বান

2

ড্যানের উত্তরের উপরে নির্মিত টাইপসক্রিপ্টের সাথে কাজ করার সময় আমার কার্যনির্বাহী (রিডুএক্স টাইপিংগুলি 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

@ ড্যান-আব্রামভ উত্তরের কেবল একটি বর্ধন , কখনও কখনও আমাদের পুনরায় সেট করা থেকে কিছু কী ধরে রাখতে পারে।

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

একটি দ্রুত এবং সহজ বিকল্প যা আমার পক্ষে কাজ করেছিল তা হ'ল রিডেক্স-রিসেট ব্যবহার করছিল । বৃহত্তর অ্যাপ্লিকেশনগুলির জন্য যা সোজা ছিল এবং কিছু উন্নত বিকল্প রয়েছে।

স্টোর তৈরি করতে সেটআপ করুন

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

রেডাক্সকে প্রাথমিক অবস্থার একই চলকটিতে রেফারেন্স থেকে আটকাতে আমার গ্রহণ:

// 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আপনি সেই হ্রাসকারীর জন্য শুনতে এবং এটি সেখানে পরিচালনা করতে পারেন।
অ্যান্ডি_ডি

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;
}

দ্রষ্টব্য: আপনি অ্যাকশন ডিফল্ট মান সেট করেছেন {}এবং আপনি ঠিক আছেন তা নিশ্চিত করুন কারণ আপনি action.typeস্যুইচ স্টেটমেন্টের ভিতরে যাচাই করার সময় ত্রুটির মুখোমুখি হতে চান না ।


0

আমি খুঁজে পেয়েছি যে গৃহীত উত্তরটি আমার পক্ষে ভাল কাজ করেছে তবে এটি ESLint no-param-reassignত্রুটিটিকে ট্রিগার করেছে - 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

ড্যান আব্রামভের উত্তর ছাড়াও, আমরা কি স্পষ্টরূপে ক্রিয়া = {প্রকার: '@@ আইএনআইটি' as পাশাপাশি রাজ্য = অপরিজ্ঞাত হিসাবে সেট করব না? উপরের ক্রিয়া প্রকারের সাথে, প্রতিটি হ্রাসকারী প্রাথমিক অবস্থায় ফিরে আসে।


0

সার্ভারে, আমার একটি ভেরিয়েবল রয়েছে: গ্লোবাল.আইএসএসআর = সত্য এবং প্রতিটি রিডুসারে আমার একটি কনস্ট রয়েছে: ইনিশিয়াল স্টেট স্টোরের ডেটা পুনরায় সেট করতে আমি প্রতিটি রিডুসার দিয়ে নিম্নলিখিতটি করি: উদাহরণস্বরূপ অ্যাপ্রেডুসার.জেএস সহ :

 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

নিম্নলিখিত সমাধানটি আমার পক্ষে কাজ করে।

প্রথম দীক্ষা আমাদের আবেদন হ্রাসকারক রাষ্ট্র তাজা এবং নতুন ডিফল্ট সঙ্গে InitialState

আমাদের একটি ক্রিয়াকলাপ যোগ করতে হবে যা ডিফল্ট অবস্থায় ধরে রাখতে অ্যাপ্লিকেশন ইনিটাল লোডে কল করে ।

অ্যাপ্লিকেশনটি লগ আউট করার সময় আমরা সাধারণ ডিফল্ট অবস্থায় পুনরায় সাইন ইন করতে পারি এবং রিডুসারটি ঠিক নতুন হিসাবে কাজ করবে ।

প্রধান অ্যাপ্লিকেশন ধারক

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

প্রধান অ্যাপ্লিকেশন হ্রাসকারী

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

গৃহীত উত্তরের একটি সমাধান সমাধান না করে প্যারামিটারাইজড নির্বাচকদের ক্যাশে সাফ করুন। আপনার যদি এর মতো একজন নির্বাচক থাকে:

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();

অন্যথায় নির্বাচকের শেষ কলের জন্য মেমোমাইজ করা মান এবং শেষ প্যারামিটারের মানগুলি এখনও স্মৃতিতে থাকবে।

কোড নমুনা এনজিআরএক্স ডক্স থেকে প্রাপ্ত


0

আমার জন্য সবচেয়ে ভাল কাজ করেছে তার initialStateপরিবর্তে সেট করা state:

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

-1

অন্য বিকল্পটি হ'ল:

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

'@@redux/INIT'আপনি যখন হ্রাসকারীদের স্বয়ংক্রিয়ভাবে প্রেরণ করেন তখন এমন অ্যাকশন টাইপ যা createStoreআপনার হ্রাসকারীদের সবারই ইতিমধ্যে ডিফল্ট রয়েছে তা ধরে নিলে এটি তাদের দ্বারা ধরা পড়বে এবং আপনার রাজ্যটিকে নতুন করে শুরু করবে। এটি রিডেক্সের একটি বেসরকারী বাস্তবায়ন বিশদ হিসাবে বিবেচিত হতে পারে, তবে ক্রেতা সাবধান ...


আমি এটি করেছি যে এটি রাষ্ট্রের পরিবর্তিত হচ্ছে না, আমি চেষ্টা করেছি @@ আইএনআইটি যা রেডাক্স ডেভল্টুলসে প্রথম অ্যাকশন হিসাবে দেখানো হয়েছে
রেজা

-3

কেবল আপনার লগআউট লিঙ্কটি পরিষ্কার সেশন করুন এবং পৃষ্ঠাটি রিফ্রেশ করুন। আপনার স্টোরের জন্য কোনও অতিরিক্ত কোডের প্রয়োজন নেই। আপনি যে কোনও সময় রাষ্ট্রকে সম্পূর্ণ পুনরায় সেট করতে চান কোনও পৃষ্ঠা রিফ্রেশ হ'ল এটি হ্যান্ডেল করার একটি সহজ এবং সহজে পুনরাবৃত্তিযোগ্য উপায়।


1
আপনি যদি এমন মিডলওয়্যার ব্যবহার করেন যা স্টোরকে স্থানীয় স্টোরেজে সিঙ্ক করে? তারপরে আপনার দৃষ্টিভঙ্গি কিছুতেই কার্যকর হয় না ...
স্পোক করুন

8
আমি কেন বুঝতে পারছি না কেন লোকেরা উত্তরগুলিকে এভাবে অগ্রাহ্য করে।
উইলিয়াম জড

লোকেরা কেন এটিকে অবমূল্যায়ন করেছে? আপনি যখন খালি বিষয়বস্তু সহ একটি নতুন রিডেক্স রাজ্য করেন, তখন মূলত আপনার এখনও মেমরির পূর্ববর্তী রাজ্য থাকে এবং আপনি তাত্ত্বিকভাবে সেগুলি থেকে ডেটা অ্যাক্সেস করতে পারেন। ব্রাউজারকে রিফ্রেশ করা আপনার নিরাপদ বাজি!
উইলহেলম Sorban

-3

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


ব্যাখ্যা করা? @ সিনানসেমেট
নিকিতা বেজনোসিকভ

পরিষ্কার হওয়ার জন্য আমি এটিকে ভোট দেইনি। তবে আমি তা নিরুৎসাহিত করি। আপনি লগইন এবং পুনরায় লোড নেভিগেট যদি আপনি সম্ভবত হ্যাঁ লগআউট হবে। তবে কেবলমাত্র আপনি নিজের রাজ্যটি হারিয়েছেন। আপনি যদি না রিডেক্স-অবিরত ব্যবহার না করেন তবে আপনি লগআউটও করবেন না। সামগ্রিকভাবে, আমি যেমন ফাংশনগুলি দেখে ঘৃণা করিwindow.location.reload();
সিনান সামেত

- এই জাতীয় ফাংশন লিখবেন না। - কেন? - আমি এটা পছন্দ করি না।
নিকিতা বেজনোসিকভ

1
পৃষ্ঠাটি পুনরায় লোড করা স্টোরের স্থিতি পুনরায় সেট করা থেকে আলাদা। এছাড়াও আপনি সম্ভবত কোনও পরিবেশে থাকতে পারেন window, যেমন- দেশীয় প্রতিক্রিয়া করুন
সর্বোচ্চ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.