question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Combine the concept of state and actions into models 🤯

See original GitHub issue

EDIT: @Alber70g suggested an even more extreme simplification:

Instead of app({ model, view }, root)app(model, view, root), but we can discuss that on another issue.

We did it once and here we go again. Like everything, there are trade-offs involved, not to mention the pain that comes with the churn. There’s also “done is better than perfect”, but Hyperapp is not done yet, and we still have some time before 1.0. I need your help to evaluate if this idea holds or not, and identify possible drawbacks or disadvantages.

The proposal (via @Alber70g) is to combine the concepts of state and actions into a new abstraction: models. A model is a regular object that holds your state props and actions.

The typical counter would look like this:

app({
  model: {
    count: 0,
    down: () => model => ({ count: model.count - 1 }),
    up: () => model => ({ count: model.count + 1 })
  },
  view: model => (
    <main>
      <h1>{model.count}</h1>
      <button onclick={model.down}>–</button>
      <button onclick={model.up}>+</button>
    </main>
  )
})

An application that is wired to state and actions from multiple sources, could look like this:

app({
  model: {
    A,
    B,
    C,
    D
  }
})

Instead of the current:

app({
  state: {
    A: state.A,
    B: state.B,
    C: state.C,
    D: state.D
  },
  actions: {
    A: actions.A,
    B: actions.B,
    C: actions.C,
    D: actions.D
  }
})

And an app that subscribes to external events.

const { tick } = app({
  model: {
    time: Date.now(),
    tick: () => ({ time: Date.now() })
  },
  view: model => <Clock time={model.time} />
})

setInterval(tick, 1000)

You can see that the app() now returns the wired model, so you can access not only actions, but also state props.

Now, you can think of models like a “module” that contains your state and actions under the same namespace.

// A counter model
const counter = {
  count: 0,
  add: n => model => ({ count: model.count + n })
}

app({
  model: { counter },
  view: ({ counter }) => (
    <main>
      <h1>{counter.count}</h1>
      <button onclick={e => counter.add(1)}>Add</button>
    </main>
  )
})

Notice how usage of the model inside the view function mirrors how you define the model above.

Pros

  • Simplify your code (save bytes!)
  • Simplify core (save bytes!)

Cons

  • Breaking change
  • Complicate saving the state to local storage, as you will have to exclude actions from the model before you save:
saveToStorage(withoutActions(model))

Notes

  • No impact on how slices work.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:15
  • Comments:66 (50 by maintainers)

github_iconTop GitHub Comments

3reactions
alber70gcommented, Dec 11, 2017

I’m glad my proposal found it’s way. I’m also happy that we can move forward. I for one would be unhappy if I’d had to fork this project for this functionality.

Let’s not forget to thank @JorgeBucaran for creating and pulling this project. He’s making sure this project doesn’t go haywire by making it a real challenge to persuade and convince and bring the right arguments to good ideas. Because of him and through this way we will be able to create something truly beautiful!

3reactions
jorgebucarancommented, Dec 7, 2017

@okwolf Good point, I totally missed it. What @vdsabev suggested is actually not correct. Not a problem for me though.

Read more comments on GitHub >

github_iconTop Results From Across the Web

State models - IBM
A state model represents the process model for one type of record. A state represents the status of a record, for example Submitted,...
Read more >
MuZero: The Walkthrough (Part 1/3) | by David Foster - Medium
In this three part series, we'll explore the inner workings of the DeepMind MuZero model — the younger (and even more impressive) brother...
Read more >
Modeling Actions through State Changes - Stanford AI Lab
In this paper we present a model of action based on the change in the state of the environment. Many actions in- volve...
Read more >
How to Build a Todo App Using React, Redux, and Immutable.js
Redux is a tiny library that acts as a container for our application state, by combining ideas from Flux and Elm. We can...
Read more >
Using Zustand with React JS! 🚀 - DEV Community 👩‍💻👨‍💻
Instead of merging, it will replace the state model. You must be careful not to delete important parts of your store such as...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found