Redux Toolkit – Solving Circular Action Dependencies

The singular struggle I have with Redux toolkit is that so much happens in the createSlice function that needing to deviating from it a little feels like a whole new pattern to adopt.

It’s crystal clear how to write the foundation, but the hallmarks of a great pattern are that you know exactly how to / where to place every type of exception you run into long term.

Say we have a simple createSlice function:

const doSomething = CaseReducer = (state, action) => {
    state.didSomething = true
}
const slice = createSlice({
  name: 'mySlice',
  reducers: { doSomething }
})

// some-other-file
slice.actions.doSomething()

If in the future, imagine this slice relies on an action from another slice (say a detail page needs to update the list page content) and we end up with a circular import. slice A imports slice B and slice B imports slice A.

How do we convert a slice action out of the helper and into its own file?

// my-shared-action.ts
// move the shared action to its own file. You will need to create its action and reducer which createSlice did automatically
const doSomething = createAction(
  "mySlice/doSomething",
  (myArg) => ({payload: myArg}) 
)
const doSomethingReducer: <CaseReducer> = (state, action) => {
  state.didSomething = true
}

// sliceA.ts
const slice = createSlice({
  name: 'mySlice',
  reducers: { },
  extraReducers: (builder) => {
    builder.addCase(doSomething.toString(), doSomethingReducer)  
  }
})

// sliceB.ts
const slice = createSlice({
  name: 'mySliceB',
  reducers: { },
  extraReducers: (builder) => {
    builder.addCase(doSomething.toString(), doSomethingReducer)  
  }
})

See we convert the createSlice action+reducer into one created from scratch in another file my-shared-action.ts using createAction and a plain reducer function.

We then import that action/reducer into two different slices, and register their reducers in their respective extraReducers properties.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s