acdlite / recompose

A React utility belt for function components and higher-order components.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting weird warning when using withStateHandlers

JulsRicketti opened this issue · comments

commented

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>

    )
  }
}

Please provide example on codesandbox

commented

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
  }
)

PR welcome

commented

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