A simpler cleaner way to update a nested state object in a reducer?

reasonreact

#1

Hi there!

I currently use something like this to change the value for a field in a nested state object:

let reducer = (action, state) =>
  switch (action) {
  | Records.ChangeSearch(text) =>
    R.Update({
      ...state,
      recordsState: {
        ...state.recordsState,
        searchQuery: text,
      },
    })
  | ...

This seems like a lot of “boilerplate” (this pattern occurs very often in my reducer functions), so I was wondering if there is a simpler/shorter way to do this in ReasonML?

Update:

I think this syntax would be nice:

R.Update({...state, recordsState.searchQuery: text})

Any love for something like this? :slight_smile:


#2

Maybe use a lens to reduce the boilerplate: https://github.com/jonlaing/rationale#infix-lens-composition


#3

Keep in mind what Evan Czaplicki (the Elm author) said about optics:

It is possible that the concept […] is harmful to code quality in that it can help you to be lax with abstraction boundaries. By making it easy to look deep inside of data structures, it encourages you to stop thinking about how to make these substructures modular, perhaps leading to an architecture that is not as nice and has extra conceptual complexity.

Source


#4

That’s an interesting point Hoichi, but I also find it interesting that Evan said that in the readme of a lens library that he himself wrote :slight_smile:


#5

Yeah, that’s funny, but I also think it lends the point more weight, coming from a guy who knows full well what lenses are and how to write them :slight_smile:
Besides, my takeout from that readme is not so much “never use lenses” as “design your boundaries”.