recompose icon indicating copy to clipboard operation
recompose copied to clipboard

Getting weird warning when using withStateHandlers

Open JulsRicketti opened this issue 6 years ago • 4 comments

I am using withStateHandlers to change a prop within a component. But I am getting an odd warning which I have no idea what it is and don't know if it may be warning me of undesired side effects or perhaps misuse of it.

This is the warning:

withStateHandlers(getContext(withStateHandlers(withProps(withStateHandlers(withProps(withState(MyComponent))))))).state: must be set to an object or null

Currently this is what my usage of withStateHandlers looks like:

export default compose(
  withStateHandlers(
    props => props.isButtonActive || false,
    {
      setButton: () => (isButtonActive) => {
        return {
          isButtonActive
        }
      }
    }
  )(MyComponent)

For context, within MyComponent I have a button that needs to be active after clicking it. However it gets it's original value from the server. For me to appropriately keep whether or not the button is active, I pass down the value I need as a prop (which is props.isButtonActive) and when the button is clicked, I call the setButton function. I don't know if relevant, but my component looks something like this:

export default MyComponent extends React.Component {
  render () {
    const { isButtonActive, setButton } = this.props
    return (
      <Button active={isButtonActive} onClick={() => setButton(!isButtonActive)}>My Button</Button>

    )
  }
}

JulsRicketti avatar Nov 07 '18 21:11 JulsRicketti

Please provide example on codesandbox

istarkov avatar Nov 08 '18 06:11 istarkov

Update: I figured it out. It turns out that it wasn't affecting anything negatively besides the warning, however, the documentation for withStateHandlers is slightly incorrect or misleading to say the very least. See here

Basically in the API format it is described that the initialState must be either an object or a function that can return any type. However, from what I can tell here, the function must also return an object. So for me, what fixed this was simply returning an object instead of boolean when I was setting the initial state:

props => ({props.isButtonActive || false}),

So for the documentation to accurately informa that it should probably be changed to the following:

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

JulsRicketti avatar Nov 08 '18 19:11 JulsRicketti

PR welcome

istarkov avatar Nov 08 '18 19:11 istarkov

Sounds good. Will try to remember to do this tonight!

JulsRicketti avatar Nov 08 '18 19:11 JulsRicketti