Recompose: [HOC suggestion] withToggle

Created on 15 Sep 2016  Â·  8Comments  Â·  Source: acdlite/recompose

Hi,

A common use case for withState is a simple toggle. Right now, a combination of withState and mapProps needs to be used for this:

withState('key', 'toggleKey', true),
mapProps(({ ...rest, key, toggleKey }) => ({ ..rest, key, toggleKey: () => toggleKey(!key) })

or the calling Component needs to explicitly include the new state:

<Button onClick={() => toggleKey(!key) />

Neither of these is a huge hassle or roadblock, but it might be nice to encapsulate this common pattern by including a withStateToggle HOC that accomplishes this precise pattern:

withStateToggle('key', 'toggleKey', true)

<Button onClick={toggleKey} />

Happy to write a PR.

Most helpful comment

Personally i create separate modules like ramda-addons, recompose-addons in src/modules and add this directory to webpack resolve.modules config. That way there is no difference between 3rd party and my local imports.

import { withHandlers } from 'recompose';
import { withStateToggle } from 'recompose-addons';

All 8 comments

Hi ;-),
this is a common misconception that some common task for you is common for all ;-)

For example I use recompose since it first releases, and I never used some kind of toggle because of controllable nature of all components. So every component with 'toggle' state always pass it's new value in onChange handler.

So in my common ;-) case there is no need to use toggle at all.

I wrote about in some other issues, it's easier to think about recompose as about a base blocks for your own hocs. This will allow to make recompose API surface as small as possible.

It's so easy to compose multiple hocs and reuse everywhere in your code.

export default (keyName, keySetterName, initialValue) => compose(
  withState(keyName, keySetterName, initialValue),
  ...blabla
)

Thanks.

I was mistaken earlier - I just checked and mapProps does not create a separate component when used after withState.

(for clarity, my comment:
As with my other PR, I'll just point out that composing building blocks is great, but having to compose multiple building blocks for a common (this would clearly depend on whether other users wanted this in the lib or not) use case where there are potential hits to creating multiple components is unfortunate.
)

building blocks for a common

You are again talking about common ;-)
toggle is not common in the react world.
In jquery - yes,
In React - no.
I wrote above about why it's not so common as you think.

use case where there are potential hits to creating multiple components is unfortunate

Please be more clear, what use case are you talking about?

Never mind, editing my post.

Personally i create separate modules like ramda-addons, recompose-addons in src/modules and add this directory to webpack resolve.modules config. That way there is no difference between 3rd party and my local imports.

import { withHandlers } from 'recompose';
import { withStateToggle } from 'recompose-addons';

I am curious if @istarkov can elaborate on his approach with some code examples. He said:

So every component with 'toggle' state always pass it's new value in onChange handler.

What does that look like?

@timkindberg The problem of toggle is that it's not a pure function and is easy to replace with pure approaches, like: setValue(!value)

I am going to close this issue because it's no longer active. Please feel free to reopen it if you have further input.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

finom picture finom  Â·  3Comments

yellowfrogCN picture yellowfrogCN  Â·  3Comments

Secretmapper picture Secretmapper  Â·  3Comments

joncursi picture joncursi  Â·  3Comments

cdomigan picture cdomigan  Â·  4Comments