admin管理员组

文章数量:1425814

I am working on a React project and using Redux for state management. I'm moving from ImmutableJS to Immer, and I'm not sure how to return the initial state with some changes. I was using merge from ImmutableJS, but not sure how to do it with Immer.

I looked everywhere and couldn't find the answer. It seems like setting draft to initial state, and then making some changes doesn't work.

export const initialState = {
  initializedAuth: false,
  isAuthenticated: false,
  user: null,
};

const authProviderReducer = (state = initialState, action) =>
  produce(state, draft => {
    switch (action.type) {
      case AUTH_USER_NO_TOKEN:
        draft.initializedAuth = true;
        draft.isAuthenticated = false;
        break;

      case AUTH_UPDATE_USER_HAVE_TOKEN:
        draft.initializedAuth = true;
        draft.isAuthenticated = true;
        break;

      case AUTH_SUCCESSFUL_LOGIN:
        draft.initializedAuth = true;
        draft.isAuthenticated = true;
        draft.user = action.payload;
        delete draft.user.session;
        break;

      case AUTH_LOGOUT: {
        // return initialState;
        // draft = initialState; doesn't work
      }
    }
  });

On AUTH_LOGOUT, I want to return the initial state and set its initializedAuth property to true.

Using Immutablejs, I was able to do it like this:

case AUTH_LOGOUT: {
    return initialState.set('initializedAuth', true);
}

I am working on a React project and using Redux for state management. I'm moving from ImmutableJS to Immer, and I'm not sure how to return the initial state with some changes. I was using merge from ImmutableJS, but not sure how to do it with Immer.

I looked everywhere and couldn't find the answer. It seems like setting draft to initial state, and then making some changes doesn't work.

export const initialState = {
  initializedAuth: false,
  isAuthenticated: false,
  user: null,
};

const authProviderReducer = (state = initialState, action) =>
  produce(state, draft => {
    switch (action.type) {
      case AUTH_USER_NO_TOKEN:
        draft.initializedAuth = true;
        draft.isAuthenticated = false;
        break;

      case AUTH_UPDATE_USER_HAVE_TOKEN:
        draft.initializedAuth = true;
        draft.isAuthenticated = true;
        break;

      case AUTH_SUCCESSFUL_LOGIN:
        draft.initializedAuth = true;
        draft.isAuthenticated = true;
        draft.user = action.payload;
        delete draft.user.session;
        break;

      case AUTH_LOGOUT: {
        // return initialState;
        // draft = initialState; doesn't work
      }
    }
  });

On AUTH_LOGOUT, I want to return the initial state and set its initializedAuth property to true.

Using Immutablejs, I was able to do it like this:

case AUTH_LOGOUT: {
    return initialState.set('initializedAuth', true);
}
Share Improve this question edited Apr 14, 2021 at 2:53 Lin Du 103k136 gold badges334 silver badges567 bronze badges asked May 15, 2019 at 11:29 Andrija PavlovicAndrija Pavlovic 1072 silver badges9 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

It looks like you are following the correct pattern, except that your reducer's AUTH_LOGOUT case should work as follow:

case AUTH_LOGOUT: {
    return draft[initializedAuth] = true;
}

About returning the intialState, there is this section in the docs:

If you want to initialize an uninitialized state using this construction, you can do so by passing the initial state as second argument to produce:

const byId = produce(
    (draft, action) => {
        switch (action.type) {
            .
            .
            .
        }
    },
    intialState <-- here
)
const appReducer = (state = initialState, action) =>
produce(state, draft => {
    switch (action.type) {
        case LOGOUT:
            return initialState;

本文标签: javascriptHow to return initial state from a reducer using ImmerStack Overflow