4

Suppose I have nested Elmish components like this: A contains B contains C.

Then if C has state and messages, these must be passed from C to B and then to A.

For example, the message and model types for B might be:

type Message = 
  | CMessage of C.Message
  | UpdateFoo of string

type Model = 
  {
    Foo : string
    C : C.Model
  }

Then update for B will do some routing:

let update message model = 
  match message with
  | CMessage m -> 
    {
      model with
        C = C.update m model.C 
    }
  | UpdateFoo foo -> { model with Foo = foo }

Then the same must be done for A consuming B messages.

This is quite verbose compared to setState, for example.

What are some strategies for managing this in Elmish?

sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
  • I don't know what setState is. Maybe throw that out of the question, or explain if it's important to enlighten us. If there's no answer coming to this question, perhaps a discussion about this on e.g. F# Slack would be fruitful in searching for a solution. I'm bored too by all this boilerplate. – Bent Tranberg Jun 13 '19 at 19:05
  • 1
    `setState` is part of React... think of it as a `mutable` store, local to each component, containing it's model. – sdgfsdh Jun 13 '19 at 19:22
  • It's important to note that setState is doing quite a bit less than update. While there may or may not be a better way to do this, I would be surprised if we can achieve that level of brevity while maintaining the explicit nature of elmish. https://elmish.github.io/elmish/parent-child.html In short having the compiler check things sometimes does mean we need to spell things out a little more thoroughly, however that doesn't mean it doesn't save time in the long run. – VoronoiPotato Jun 24 '19 at 02:14

1 Answers1

2

If you create a hierarchy of model types, then you need to route messages through that hierarchy in update. If you don't want to route messages through that hierarchy in update, then don't create a hierarchy of model types. That would mean you have a flat model.

However, I think that having a flat model is not sustainable. As your application grows in complexity, you will need to manage that complexity by grouping related concepts into (sub-)modules that contain their own model types.

This is quite verbose compared to setState, for example. What are some strategies for managing this in Elmish?

The function setState is meant for library authors. Your question is about specific model and message types, so my impression is that you are an "end user" of Elmish (instead of a library author). As such, I think it is unfair to compare your example update function to some alternative that uses setState since you should be using setState.

I think this verboseness you describe is the tradeoff for tightly controlling mutation. By using Elmish, you are saying that you want to tightly control mutation (by letting nearly all of it happen in Elmish instead of your code), so I think think this verboseness is necessary.

Tyson Williams
  • 1,630
  • 15
  • 35