Crank: Shared functionality across event listeners

Created on 16 Apr 2020  路  3Comments  路  Source: bikeshaving/crank

In the spirit of DRY, would this be an appropriate pattern for sharing functionality between event listeners (e.g. writing to local storage, triggering a component refresh)?

function* App() {
    // ...
    const onEvent = ev => {
        switch (ev.type) {
          case "todo.create":
            todos.push({
              id: nextTodoId++,
              title: ev.detail.title,
              completed: false
            });
            break;
          case "todo.destroy":
            todos = todos.filter(todo => todo.id !== ev.detail.id);
            break;
        }
        this.refresh();
        save(todos);
    };

    this.addEventListener("todo.create", onEvent);
    this.addEventListener("todo.destroy", onEvent);
    // ...
}

TODO MVC Sandbox Example:
https://codesandbox.io/s/epic-tu-pnckp?file=/src/index.js

I realize this may be a JS question, not a crank question...

Most helpful comment

This looks interesting! It almost looks like a Redux reducer, which is kinda cool. I also like that it encapsulates the refresh/save logic for each event. My only worry is that the type of ev is kinda complicated. It鈥檚 a union of all the events that are available in TodoMVC. Dunno if this is good or bad but something to think about!

All 3 comments

This looks interesting! It almost looks like a Redux reducer, which is kinda cool. I also like that it encapsulates the refresh/save logic for each event. My only worry is that the type of ev is kinda complicated. It鈥檚 a union of all the events that are available in TodoMVC. Dunno if this is good or bad but something to think about!

I like it, you could actually externalize it into separate file for only dealing with events:

// reducer.js
export function reducer() {
  const onEvent = (ev) => {
    switch (ev.type) {
      case "todo.create":
        todos.push({
          id: nextTodoId++,
          title: ev.detail.title,
          completed: false,
        });
        break;
      case "todo.destroy":
        todos = todos.filter((todo) => todo.id !== ev.detail.id);
        break;
    }
    this.refresh();
    save(todos);
  };

  this.addEventListener("todo.create", onEvent);
  this.addEventListener("todo.destroy", onEvent);
}

and later kinda use it as hooks in the component and even reuse it:

function* App() {
  reducer.call(this);

  /* ... */
}

These are cool ideas, but I think I鈥檓 going to keep the TodoMVC with separate event listener callbacks, just cuz that feels crankier to me. But I encourage you to experiment! Closing the issue for housekeeping purposes, but feel free to continue the discussion!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xkxx picture xkxx  路  7Comments

GormanFletcher picture GormanFletcher  路  4Comments

palavrov picture palavrov  路  6Comments

virtualfunction picture virtualfunction  路  5Comments

malcolmstill picture malcolmstill  路  5Comments