1

I am having trouble with my Redux store in cases where I am passing params through a Thunk action. In cases were there is no param, my store is populating correctly. The action is completing successfully and I can see that the data has been returned to the front end by the success / fulfilled message of my action but there is no sign of it going into the store as state.

I had an instance previously where the array list was named incorrectly from the backend however this is not the case this time.

Is there anything that stands out why my store isn't populating with the state data?

action working correctly

but not populating in the store in the users section

action

export const requireUserDiveLogData = createAsyncThunk(
    'users/requireData', // action name
    // action expects to be called with the name of the field
    async (userId) => {
        // you need to define a function to fetch the data by field name
        const response = await userDiveLogList(userId);
        // what we return will be the action payload
        return response.data;
    },
    // only fetch when needed: https://redux-toolkit.js.org/api/createAsyncThunk#canceling-before-execution
    {
        // _ denotes variables that aren't used -  the first argument is the args of the action creator
        condition: (_, { getState }) => {
            const { users } = getState(); // returns redux state
            // check if there is already data by looking at the didLoadData property
            if (users.didLoadDiveLogData) {
                // return false to cancel execution
                return false;
            }
        }
    }
)

reducer

export const userSlice = createSlice({
    name: 'users',
    initialState: {
        userDiveLogList: [],
        didLoadDiveLogData: false,
    },
    reducers: {
        [requireUserDiveLogData.pending.type]: (state) => {
            state.didLoadDiveLogData = true;
        },
        [requireUserDiveLogData.fulfilled.type]: (state, action) => {
            return {
                ...state,
                ...action.payload
            }
        },
    }
})
Lin Du
  • 88,126
  • 95
  • 281
  • 483
James Gee
  • 129
  • 1
  • 3
  • 24
  • 1
    Don't understand your question? What are your trying to do? What result do you expect? – Lin Du May 21 '21 at 02:09
  • I am trying to add the state to the store so I can access it. I can see that action payload is succeeding but the state isn't populating in the users field were it should be. – James Gee May 21 '21 at 05:31

1 Answers1

1

You should use extraReducers rather than reducers to handle actions produced by createAsyncThunk and createAction functions.

Besides, Redux Toolkit's createReducer and createSlice automatically use Immer internally to let you write simpler immutable update logic using "mutating" syntax. You don't need to do the shallow copy work by yourself.

E.g.

// @ts-nocheck
import {
  configureStore,
  createAsyncThunk,
  createSlice,
} from '@reduxjs/toolkit';

async function userDiveLogList(userId) {
  return { data: { userDiveLogList: [1, 2, 3] } };
}

export const requireUserDiveLogData = createAsyncThunk(
  'users/requireData',
  async (userId) => {
    const response = await userDiveLogList(userId);
    return response.data;
  },
  {
    condition: (_, { getState }) => {
      const { users } = getState();
      if (users.didLoadDiveLogData) {
        return false;
      }
    },
  }
);

const userSlice = createSlice({
  name: 'users',
  initialState: {
    userDiveLogList: [],
    didLoadDiveLogData: false,
  },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(requireUserDiveLogData.pending, (state) => {
        state.didLoadDiveLogData = true;
      })
      .addCase(requireUserDiveLogData.fulfilled, (state, action) => {
        state.userDiveLogList = action.payload.userDiveLogList;
      });
  },
});

const store = configureStore({
  reducer: {
    users: userSlice.reducer,
  },
});

store.dispatch(requireUserDiveLogData()).then(() => {
  console.log(JSON.stringify(store.getState(), null, 2));
});

Output in the console:

{
  "users": {
    "userDiveLogList": [
      1,
      2,
      3
    ],
    "didLoadDiveLogData": true
  }
}
Lin Du
  • 88,126
  • 95
  • 281
  • 483