Search code examples
javascriptreactjsreduxreact-reduxredux-toolkit

React Redux Toolkit - Can we Dispatch/Call from one reducer's action to another reducer's action to change state variable


Here I have two state slices and I need to dispatch a method of slice1 within slice2.

How can I call a reducer's action of slice 1 from extra reducer's action of callApiSlice

const slice1 = createSlice({
  initialState,
  reducers: {
    login: (state) => {
      state.login = { email: '[email protected]', api_keys: false};
    },
    setApiKey: (state) => {
      state.login.api_keys = true;
    },
  },
}

export const callApi = createAsyncThunk(
  "call-api",
  async (payload, thunkAPI) => {
    try {
      const res = await axios.post( process.env.REACT_APP_API_URL + "/save", payload);
      return res.data;
    } catch (error) {
      return thunkAPI.rejectWithValue(error.response.data);
    }
  }
);

const callApiSlice = createSlice({
  name: "callApiSlice",
  initialState,
  reducers: {},
  extraReducers: {
    [callApi.fulfilled]: (state, action) => {
      // how to call Slice 1 reducer's action setApiKey to change in login state
    }
  }
});

export default callApiSlice.reducer;

Solution

  • You can't directly invoke reducer functions, but if I'm correctly understanding your question it seems you want "setApiKey" reducer function to run upon dispatch of the callApi.fulfilled action. Redux state slices/reducer functions (i.e. the state reducer tree) are technically passed every action that is dispatched, and can respond to any of them. Add a reducer case in the slice1 state slice to handle the callApi.fulfilled action.

    Example:

    const slice1 = createSlice({
      name: "slice1",
      initialState,
      reducers: {
        login: (state) => {
          state.login = { email: '[email protected]', api_keys: false };
        }
        setApiKey: (state) => {
          state.login.api_keys = true;
        }
      },
      extraReducers: {
        [callApi.fulfilled]: (state) => { // <-- respond/react to action
          state.login.api_keys = true;
        },
      },
    }
    
    export const callApi = createAsyncThunk(
      "call-api",
      async (payload, thunkAPI) => {
        try {
          const { data } = await axios.post( process.env.REACT_APP_API_URL + "/save", payload);
          return data;
        } catch (error) {
          return thunkAPI.rejectWithValue(error.response.data);
        }
      }
    );
    
    const callApiSlice = createSlice({
      name: "callApiSlice",
      initialState,
      extraReducers: {
        [callApi.fulfilled]: (state, action) => {
          ...
        }
      },
    });