Recompose: withStateHandlers callback

Created on 12 Sep 2017  路  4Comments  路  Source: acdlite/recompose

Calling a callback after setState() is a common and helpful React pattern, I'm confused why withStateHandlers doesn't support it?

Eg. I want to update a searchString state item, and then trigger an async load that uses that state.

withStateHandlers({
    searchString: ''
}, {
    setSearchString: (state) => (newString) => ({searchString: newString})
}),
withHandlers({
    load: ({searchString}) => () => load(searchString)
}),
withHandlers({
    onSearchChange: ({setSearchString, load}) => (newString) => setSearchString(newString, load)
})

Most helpful comment

In withState and withReducer you support callback. I do not understand why in this function you do not want to provide callback.

All 4 comments

Because the only thing you can do in that callback with current api is to call some side-effect.
We don't want to provide such api.
Also you can search issues I wrote about in other places.

In withState and withReducer you support callback. I do not understand why in this function you do not want to provide callback.

EDIT: I figured out why withStateHandlers is different from withState.

Unlike withState, the state updater prop that withStateHandlers passes can accept an arbitrary number of parameters. Because of this, the withStateHandlers HOC would need to know which parameter was the callback.

One might assume that the last parameter passed could be the callback, but that wouldn't work in the case below:

function onStateUpdated(newState) {
  // Do something with the newState
}

function MyComponent({ myState, myStateHandler }) {
  return (
    <button onClick={() => myStateHandler(5, onStateUpdated)}>
      Click me to update state
    </button>
  )
}

const MyComponentWithStateHandlers = withStateHandlers({
  myState: 0,
}, {
  myStateHandler: () => (paramA, paramB = 0, paramC = 0) => ({ 
    myState: paramA +  paramB +  paramC,
  }),
})(MyComponent)

Note that, since the onStateUpdated callback is passed as the 2nd (and last) parameter to the state handler, the withStateHandlers HOC would need to decide whether to pass it as a parameter to the state handler or call it as a function after the state updates.

@dolezel - hope this helps


@istarkov - could you provide a link to the issues you wrote in other places? I'm having trouble understanding why we would want to support a post setState callback on withState and withReducer, but not on withStateHandlers.

As a workaround I'm just making a withHandler which wraps the withState setter and exposes a callback in its signature. It's not the cleanest but I don't like the alternatives.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

isubasti picture isubasti  路  3Comments

nemocurcic picture nemocurcic  路  3Comments

uriklar picture uriklar  路  4Comments

rndmerle picture rndmerle  路  3Comments

franklinkim picture franklinkim  路  3Comments