Skip to content
This repository has been archived by the owner on Sep 25, 2020. It is now read-only.

Latest commit

 

History

History
143 lines (109 loc) · 3.64 KB

redux-reducer.md

File metadata and controls

143 lines (109 loc) · 3.64 KB

@ReduxReducer

Marks a class method as redux reducer and wires the reducer method against one or many redux actions.

@ReduxAction(string|string[]|Function|Function[])

Reference variants

By prototype

The recommended and simplest way is to wire the reducer directly via the prototype with the action method. This gives you the advantage that TypeScript can validate the return value of the ReduxAction against the expected payload of your Reducer function. This is also the only way to enable IDE refactoring.

TypeScript support

class SomeReducerClass {

  @ReduxReducer(SomeActionClass.prototype.addItem) // addItem returns string
  public addItem(state: SomeState, action: ReduxActionWithPayload<string>): SomeState {
    return {
       ...state,
       items: state.items.concat(action.payload),
     };
  }
  
}

The reducer can also listen to several actions at the same time:

class SomeReducerClass {

  @ReduxReducer([
    SomeActionClass.prototype.addItem, // addItem returns string
    SomeActionClass.prototype.addDefaultItem, // addDefaultItem returns string
  ])
  public addItem(state: SomeState, action: ReduxActionWithPayload<string>): SomeState {
    return {
       ...state,
       items: state.items.concat(action.payload),
     };
  }
  
}

Or you can decorate the reducer method multiple times:

class SomeReducerClass {

  @ReduxReducer(SomeActionClass.prototype.addItem) // addItem returns string
  @ReduxReducer(SomeActionClass.prototype.addDefaultItem) // addDefaultItem returns string
  public addItem(state: SomeState, action: ReduxActionWithPayload<string>): SomeState {
    return {
       ...state,
       items: state.items.concat(action.payload),
     };
  }
  
}

The array notation and the TypeScript type check currently only work well for actions which return the same type. So if you have something like this, TypeScript will throw a type error:

class SomeReducerClass {

  @ReduxReducer([
    SomeActionClass.prototype.addItem, // addItem returns string
    SomeActionClass.prototype.addItems // addItems returns string[]
  ])
  public addItem(state: SomeState, action: ReduxActionWithPayload<string | string[]>): SomeState {
    return {
       ...state,
       items: state.items.concat(action.payload),
     };
  }
  
}

But you can fall back to the following solution:

class SomeReducerClass {

  @ReduxReducer(SomeActionClass.prototype.addItem) // addItem returns string
  @ReduxReducer(SomeActionClass.prototype.addItems) // addItems returns string[]
  public addItem(state: SomeState, action: ReduxActionWithPayload<string | string[]>): SomeState {
    return {
       ...state,
       items: state.items.concat(action.payload),
     };
  }
  
}

By string

It is also possible to refer directly to an action by string. However, this option should only be used if there is no other option. You can also specify this as an array or decorate the method multiple times.

class SomeReducerClass {

  @ReduxReducer('some-action-type')
  public addItem(state: SomeState, action: ReduxActionWithPayload<string>): SomeState {
    return {
       ...state,
       items: state.items.concat(action.payload),
     };
  }
  
}

Activation

Don't forget to activate your reducer! You've to add the reducer class to the reducers array like this:

@NgModule({
  imports: [
    ReduxModule.forRoot({
      state: {
        provider: SomeStateProvider,
        reducers: [ SomeReducerClass ],
      }
    }),
  ],
  providers: [SomeStateProvider]
})