To add to that, there is a profusion of fine-grained actions like SetFirstName, SetLastName is endemic in Redux-inspired codebases. They are a lot of noise, but more importantly, they force us to keep all our domain logic in a single massive reducer, with no encapsulation between different sections.
This can be improved by using coarse-grained actions like say `UpdatePerson(person)`. And this new `person` value can be obtained by the event handler itself when the user changes the name. However, the actual logic can sit inside a Person module, allowing us to do something like: `onChange=dispatch(UpdatePerson(Person.setFirstName(newName, currentPerson))`
This approach lets us keep the behaviour close to the view while encapsulating the actual implementation inside a rich domain model.
As I note in my other comment, this approach is fundamentally unsound in Elm.
The view is generated in its own thread synced to the browser's rendering system. It is entirely possible for the model to have changed without the view having been updated yet to match.
If your model changes under your feet while you use this approach, it result in you silently overwriting that change with the old data.
This can be improved by using coarse-grained actions like say `UpdatePerson(person)`. And this new `person` value can be obtained by the event handler itself when the user changes the name. However, the actual logic can sit inside a Person module, allowing us to do something like: `onChange=dispatch(UpdatePerson(Person.setFirstName(newName, currentPerson))`
This approach lets us keep the behaviour close to the view while encapsulating the actual implementation inside a rich domain model.