---
# System prepended metadata

title: Redux alignement

---

# Redux alignement

The goal of this meeting is to present how I've implemented Redux with the CaseCreationV2 feature. Before reading this documentation, which is about our project, please make sure to read this: [Redux - Usage with typescript](https://redux-toolkit.js.org/usage/usage-with-typescript#introduction)

## Structure

```
store/
    - features/
        - caseInit/
            - initialState.ts
            - caseInitSlice.ts
            - selectors.ts
            - thunks.ts
        - arch/
        - stepBar/
        - selectors.ts
        - thunks.ts
    - types/
    - hooks.ts
    - store.ts
    
```

### `store`
The whole state of the app (here, feature)
```
export const store = configureStore<RootState>({
  reducer: {
    stepBar: stepBarSlice.reducer,
    caseInit: caseInitSlice.reducer,
    maxilla: maxillaSlice.reducer,
    mandible: mandibleSlice.reducer,
  },
})
```
### `initialState`
useful to compare changes, or reset data without reloading the whole page
### `<feature>Slice`
contains the reducers of the feature:
```
export const caseInitSlice = createSlice({
  name: "caseInit",
  initialState: initialState,
  reducers: {
    changePatientFirstName: (state, action: PayloadAction<string>) => {
      state.patient.firstName = action.payload
      if (state.dataChecked) {
        checkFirstName(state)
      }
    },
    // ...
  },
  extraReducers(builder) {
    builder
      .addCase(createCaseDraft.pending, (state) => {
        state.creatDraftStatus = "loading"
      })
      .addCase(createCaseDraft.fulfilled, (state, action) => {
        state.creatDraftStatus = "succeeded"
        state.draftId = action.payload.id
        const newPatient = {
          birthDate: action.payload.patient.birthDate,
          firstName: action.payload.patient.firstName,
          lastName: action.payload.patient.lastName,
          middleName: action.payload.patient?.middleName ?? "-",
          gender: action.payload.patient.gender,
          customPatientId: action.payload.customPatientId,
          patientId: action.payload.patientId,
        }
        state.patient = newPatient
        state.patientInit = newPatient
        state.caseOwnerB2cUserId = action.payload.caseOwnerB2cUserId
        state.caseOwnerB2cUserIdInit = action.payload.caseOwnerB2cUserId
        state.caseType = action.payload.caseType
        state.caseTypeInit = action.payload.caseType
      })
      .addCase(createCaseDraft.rejected, (state, action) => {
        state.creatDraftStatus = "failed"
        state.errors.createCaseDraft = action.payload
      })
      // ...
  },
})
```
the actions creators are then exported from the slice (at the end of the file):
```
export const {
  changePatientFirstName,
  // ...
} = caseInitSlice.actions


// In another file ------

const dispatch = useAppDispatch()
dispach(changePatientFirstName(patientFirstName))
```
this generates the following action: `{type: "caseInit/changePatientFirstName", payload: patientFirstName}`

### `selectors`
A selector is a function that takes the state as parameter and returns a part of the state or a computation of the state
    - part of the state: arrow function ie `
    const selectCaseInit = (state) => state.caseInit
    `
    - computation of the state: use the `createSelector` function, it memoizes the result of the computation
    ```
    const selectIsGettingDraft = createSelector(
        [selectCaseInit], 
        (caseInit) => caseInit.getDraftStatus === "loading")
    ```
    , see https://redux-toolkit.js.org/api/createSelector


### `thunks`
A thunk 

## Behaviour

### Immutability

`createSlice()` uses immer, which means it simplifies a lot how we change the state, see https://redux-toolkit.js.org/usage/immer-reducers.

Example of what we can avoid thanks to it:
```
function handwrittenReducer(state, action) {
  return {
    ...state,
    first: {
      ...state.first,
      second: {
        ...state.first.second,
        [action.someId]: {
          ...state.first.second[action.someId],
          fourth: action.someValue,
        },
      },
    },
  }
}
```

would become
```
function handwrittenReducer(state, action) {
  state.first.second[action.someId].fourth = action.someValue
}
```
:+1: