The road to hell is paved by avoiding state management and side-effects

The whole point of a programs are to alter state and create side-effect

One of the most bizzare things about programming to me is how developers go out of there way to avoid doing the very thing that programs are suppose to do: change state and create side-effects. I was reminded of this oddity once again with this tweet about JavaScript:

Screenshot of somebody tweeting about a wrapper

These two options were presented with the question, “which one is clearer?”

I think none of them, but let’s get into it before I go there.

React

The React code has less lines, but it has abstractions baked into it that obscure the example like useEffectEvent and useEffect.

export function App({ bpm }) {
  const tick = useEffectEvent(() => {
    console.log("BPM:", bpm);
  });

  useEffect(() => {
    let id = setInterval(tick, bpm);
    return () => clearInterval(id);
  }, [bpm]);

  return <div>{bpm}</div>;
}

Ok, great, those abstractions …

Remix

The Remix example also has abstractions like setupProps and the Remix.Handle

export function App(
  this: Remix.Handle,
  setupProps: { bpm: number }
) {
  let bpm = setupProps.bpm;
  let interval = 0;

  const makeInterval = () => {
    clearInterval(interval);
    setInterval(() => {
      if (this.signal.aborted) {
        clearInterval(interval);
      }
      console.log("BPM:", bpm);
    }, bpm);
  };

  makeInterval();

  return (updateProps: { bpm: number }) => {
    if (updateProps.bpm !== bpm) {
      bpm = updateProps.bpm;
      makeInterval();
    }
    return <div>{bpm}</div>;
  };
}

It’s more lines of code, and many in the thread were commenting that they prefer this example because its clearer.

HTML and JavaScript

Let’s have a look at the most concrete example that will get ripped to shreds by any self-respecting JavaScript developer: a brittle, concrete implementation that directly manipulates the DOM.

<!DOCTYPE html>
<html>
  <body>
    <div id="bpm"></div>
    <script>
      let bpm = 70;

      function tick() {
        console.log("BPM:", bpm);
        document.getElementById("bpm").textContent = bpm;
        setTimeout(tick, bpm);
      }

      tick();
    </script>
  </body>
</html>

State changes and side-effects are OK

I’ve talked to Elm developers…

Do you want to learn Phlex 💪 and enjoy these code examples?

Support Beautiful Ruby by pre-ordering the Phlex on Rails video course.

Order the Phlex on Rails video course for $379 $379