Recompose: How to debounce?

Created on 20 Jul 2017  路  4Comments  路  Source: acdlite/recompose

const Form = compose(
  withState('model', 'setModel', {name:'', age:''}),
)(({model, setModel}) => {
  const errors = jsonschema.validate(schema, model);
  return <form>
    <input value={model.name} onChange={e=>setModel({...model, name:e.target.value})}/>
    <Error error={errors.name}/>
    <input type="number" value={model.age} onChange={e=>setModel({...model, age:parseInt(e.target.value)})}/>
    <Error error={errors.age}/>
    <button>submit<button>
  </form>
})

Just like code above, I need to some computed-props(those validate errors is computed errors)...

But in fact, I don't need it instantly. the validate method can be debounced.

So I advice you a debounce method...

// debounceState(stateName, debounced_props_to_state_func, state_when_debounced_func_returned_undefined, miliseconds);

const Form = compose(
  withState('model', 'setModel', {name:'', age:''}),
  debounceState('errors', ({model}) => jsonschema.validate(schema, model), {}, 500),
)(({model, setModel, errors}) => {
  return <form>
    <input value={model.name} onChange={e=>setModel({...model, name:e.target.value})}/>
    <Error error={errors.name}/>
    <input type="number" value={model.age} onChange={e=>setModel({...model, age:parseInt(e.target.value)})}/>
    <Error error={errors.age}/>
    <button>submit<button>
  </form>
})

I don't know if this debounceState function can be composed by the functions in recompose. If recompose can, how? If not, can you add it in recompose, or even extract a more common pattern?

Most helpful comment

I don't think it's a good idea to debounce props,
better to debounce event handlers, moving all side-effects caused by debounce out of render cycle (lifecycle).

Having this in mind you can debounce any method using withPropsOnChange, like

withPropsOnChange(
  ['methodName'], 
  ({ methodName }) => ({
    methodName: debounce(methodName, time),
  })
)

so it will be called once if methodName is unchangeable.

All 4 comments

Well, it's somewhat like mapProps...But essentially, they are different...

I don't think it's a good idea to debounce props,
better to debounce event handlers, moving all side-effects caused by debounce out of render cycle (lifecycle).

Having this in mind you can debounce any method using withPropsOnChange, like

withPropsOnChange(
  ['methodName'], 
  ({ methodName }) => ({
    methodName: debounce(methodName, time),
  })
)

so it will be called once if methodName is unchangeable.

Yeah, withPropsOnChange is what I want... Well, I am indeed not familiar with recompose....
Thanks...

@istarkov thanks for your snippet and I made an POC with CodeSandBox

https://codesandbox.io/s/ryp0oqrmqn

Was this page helpful?
0 / 5 - 0 ratings

Related issues

franklinkim picture franklinkim  路  3Comments

nemocurcic picture nemocurcic  路  3Comments

uriklar picture uriklar  路  4Comments

jeron-diovis picture jeron-diovis  路  4Comments

cdomigan picture cdomigan  路  4Comments