Skip to content

Commit

Permalink
update: Add alternative to event switch
Browse files Browse the repository at this point in the history
Another way of handling multiple events and avoid boilerplate is to use
a `handlers` map. This makes sure that all handler calls are performed
in O(1) instead of O(n) for worst case scenario.

Signed-off-by: Adrian Oprea <[email protected]>
  • Loading branch information
oprearocks committed Mar 28, 2017
1 parent 576cda6 commit 288f73d
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions patterns/12.event-switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,53 @@ handleEvent({type}) {
}
}
```

An alternative to the switch statement would be to use an event handlers hash map.

```javascript
const handlers = {
click: () => require("./actions/doStuff")(/* action dates */),
mouseenter: () => this.setState({ hovered: true }),
mouseleave: () => this.setState({ hovered: false }),
default: () => console.warn(`No case for event type "${type}"`)
};
```

You would then have your `handleEvent` function check if the event type has a corresponding handler,
in the handlers object, otherwise use the `default` case.
This way, you don't have to modfiy `handleEvent` each time you need to handle a new event.

```javascript
handleEvent({type}) {
// Avoid mouseEnter, MouseLeave, Click
const NORMALIZED_TYPE = type.toLowerCase();

// If we have no registered handlers, we always use the 'default'
const HANDLER_TO_CALL = NORMALIZED_TYPE in handlers ? NORMALIZED_TYPE : 'default';

// No matter how many handlers we end up having in our `handlers` map, this code doesn't modify
handlers[HANDLER_TO_CALL].bind(this)();
}
```

You may also use `try..catch` and avoid performing key lookups to validate handler presence

```javascript
handleEvent({type}) {
try {
handlers[type.toLowerCase()].bind(this)();
} catch (e) {
handlers['default'].bind(this)();
}
}
```

Note that you have to bind your handler to the component &mdash; `handler.bind(this)` &mdash; before calling it.
This makes sure that `this` doesn't point to the `handlers` object when one of the functions is invoked.

Alternatively, for simple components, you can call imported actions/functions directly from components, using arrow functions.
```javascript
<div onClick={() => someImportedAction({ action: "DO_STUFF" })}
```

Don’t fret about performance optimizations until you have problems. Seriously don’t.

0 comments on commit 288f73d

Please sign in to comment.