1

I have some reducers that are similar, receiving same action, how can I deduplicate the code below?

 const gridApiReducer = (state: GridApi, action: { type: string; value: GridApi }) => {
    switch (action.type) {
        case "UPDATE":
            return action.value;
        default:
            return state;
    }
};

const columnApiReducer = (state: ColumnApi, action: { type: string; value: ColumnApi}) => {
    switch (action.type) {
        case "UPDATE":
            return action.value;
        default:
            return state;
    }
};

const [gridApi, setGridApiByDispatch] = useReducer(gridApiReducer, {} as GridApi);
const [columnApi, setColumnApiByDispatch] = useReducer(columnApiReducer, {} as ColumnApi);
appletabo
  • 239
  • 2
  • 12

2 Answers2

2

Define your reducer as a generic function:

const apiReducer = <Api extends GridApi | ColumnApi>(
  state: Api, action: { type: string; value: Api },
) => {
  switch (action.type) {
    case 'UPDATE':
      return action.value;
    default:
      return state;
  }
};

const [gridApi, setGridApiByDispatch] = useReducer(apiReducer, {} as GridApi);
const [columnApi, setColumnApiByDispatch] = useReducer(apiReducer, {} as ColumnApi);
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
0

+1 for above response as well, you are looking for generic TS functions:

const createReducer = <T extends object>()=> {
  return (state: T, action: { type: string, value: T } ): T => {
    switch (action.type) {
      case "UPDATE":
        return action.value;
      default:
        return state;
    }
  };
}

const gridApiReducer = createReducer<GridApi>();
const columnApiReducer = createReducer<ColumnApi>();
Passersby
  • 1,092
  • 9
  • 11