Can I split redux toolkit slice to multiple files and avoid circular dependency?

Viewed 102

I'm getting my feet wet with redux toolkit but I'm having some trouble organizing my code. The redux toolkit examples I see seem to put all reducer/action/side effect code in a single file and calling it a day. This doesn't sit well with me for an editor I'm working on, the resulting file is too many lines long and would be difficult to maintain so I'd like to break it up into at least two files, one for selectors and one for reducer/actions/side effects (async thunks)

The result looks a bit like this (this is a simplified version of my code, my files are considerably longer), first I have editor-slice.ts:

export const initialState = {
  data: Row[];
  errors: RowError[];
}
export type EditorState = typeof initialState;
const autoSave = createAsyncThunk(async (_: any, { getState }) => {
   const rows = EditorSelectors.getData(getState());
   // sync up with server
});
const { action, reducer } = createSlice(
  name: EDITOR_KEY,
  initialState,
  reducer: {
    ....
  },
  extraReducers: {
    builder
      .addCase(autoSave.pending, ....)
      .addCase(autoSave.rejected, ...)
      .addCase(autoSave.fulfilled, ...)
  }

and separately I have editor-selectors.ts:

export class EditorSelectors {
  static getRootState(state): EditorState {
    return state[EDITOR_KEY];
  }
  static getData = createSelector(
    EditorSelectors.getRootState,
    (state) => state.data,
  );
}

My problem is that I would like to reuse my selectors within my side effects (async thunks) but this leads to a circular dependency because the selectors need the EditorState type that is defined in editor-slice.ts. Is there a way to structure these in a way that the circular dependency is avoided and I don't need to inline selector logic within my async thunks?

0 Answers
Related