2

At my job we use recompose, and we use this kind of curried functions, that to me seem overly complicated and make my brain hurt.

Can anyone explain in english how this works?

Thanks

  withStateHandlers(({ readAt, isSender }) => ({ trackVisibility: !isSender && !readAt }), {
    updateTrackVisibility: () => () => ({
      trackVisibility: false,
    }),
  }),

I know readAt and isSender, are coming from a fragment, declared above. The most confusing part is the function that returns another function after updateTrackVisibility ???

  • 1
    withStateHandlers is called with two parameters. The first is a function that accepts two parameters and returns a new object, the second is an object with a property that contains a function that returns another function that returns a similar object. None of those arrow functions are necessary, so if it helps you understand it, you could replace them with regular functions. – Kevin B Mar 27 '19 at 16:26
  • The pattern `() =>` indicates either a deferred computation (explicit lazy evaluation so to speak) or a function that ignores its argument. `updateTrackVisibility` probably expresses the latter. However, the result value is hard coded, which renders the nested arrow function pretty useless. I'd prefer something like this: `const comp = f => g => x => f(g(x)); const constant = x => _ => x; const constant2 = comp(constant) (constant)` and then `constant2(false) (true) (true)` yields `false`. –  Mar 27 '19 at 17:25
  • Bad code will make anyone's brain hurt. The double `() => () => ...` is a serious [code smell](https://en.wikipedia.org/wiki/Code_smell). @Kevin B, you don't call a function with parameters, you call a function with arguments; arguments are bound to a function's parameters. – Mulan Mar 28 '19 at 03:05

1 Answers1

1

From recompose API:

withStateHandlers(
  initialState: Object | (props: Object) => any,
  stateUpdaters: {
    [key: string]: (state:Object, props:Object) => (...payload: any[]) => Object
  }
)

props are the props passed from the parent (or an HOC above)

state is passed from the object created in the initialState

payload params are passed from the place we triggered the function (handler)

Which means in your code:

first parameter - ({ readAt, isSender }) => ({ trackVisibility: !isSender && !readAt }) - make a prop called trackVisibility (with the coded value)

second parameter - add a function which when triggered, makes the trackVisibility to be false

Another (contrived) example:

const enhancer = withStateHandlers(({ title, text, maxChars }) => ({ isLongTitle: title.length > maxChars, text }), {
  addText: (state, props) => (text) => ({
    text: state.text + text,
    isLongTitle: state.text.length + text.length > props.maxChars
  }),
})

const MyComponent = enhancer(props => {
  return (
    <input onChange={event => props.addText(event.target.value)} />
  )
}
Community
  • 1
  • 1
Edan Chetrit
  • 4,713
  • 2
  • 20
  • 20