Event handlers

Inspiring some of existing State Managers, I`ve decided that the best way is to separate Events and Handlers instead of making "dispatching actions" and also to make different types of the Handlers.

Actions

First type of handlers are Actions. It is a handler that takes one Event, calculate something and return another Event. In a beginning I separated it for server-side logic - making requests and getting or putting some data. That`s why Event payload can be asyncronous - you can return Promise or Observable in payload and it would be unpacked.

So if you want to put your server interaction - Actions is the best way.

// ActionFn for EventScheme
const DownloadFile: ActionFn<State, string> = (filename: string) =>
    new FoxEvent('FileDownloaded', fileService.get(filename))

// Decorated method for Store class
@Action('DownloadFile')
downloadFile(filename: string): FoxEvent<Blob> {
    return new FoxEvent('FileDownloaded', fileService.get(filename))
}

Reducers

Familiar concept from other State Managers, which was populated by Redux is Reducer - small function which changing state on some action of event.

In Foxstore Reducer is also a tool to change state. It contains function which have access to actual state as parameter and returns some part of the State which would be merged deeply to common State. In a best way, reducer is pure function that get payload of Event, get previous state and return diff for new state.

// ReducerFn for Event Scheme
const addItems: ReducerFn<State, Item[]> = (items: Item[], state: State) => ({
    items: state.items.concat(items),
});

// Decorated method in StoreClass
@Reducer('AddItems')
addItems(items: Item[], state: State): Partial<State> {
    return {
        items: state.items.concat(items),
    }
}

Effect

The simplest type of handler which has no requirements. It is just side effect which gets payload and actual state and do something. No one cares what it would return, no one uses it.

It is useful when you want to make some request to send stats or just change something that not connected with this store.

// EffectFn for Event Scheme
const saveSettings = (settings: Settings) =>
    serverStorage.save('settings', settings)
    
// Decorated method of StoreClass
@Effect('SettingsChanged')
saveSettingsToServer(settings: Settings): void {
    this.serverStorage.save('settings', settings);
}

Last updated