slorber / awesome-debounce-promise

Debounce your API calls easily and stay in promised land.
https://sebastienlorber.com
391 stars 9 forks source link

Accessing state with debounce #6

Closed ghost closed 5 years ago

ghost commented 5 years ago

Is there a way to access the state when calling debounce function?

I want to setState({saving: true}) when the debounce function runs so the user knows when a save is happening and a setState({saving: true}) when it is finished. I know I can do it when it finishes but I never really know when it runs because I can't access state outside of the class.

slorber commented 5 years ago

Hi,

Not sure to exactly understand your usecase but here is an example:

class SomeComp extends React.Component {
  state = {
    saving: false,
  };

  onSave = async () => {
    this.setState({ saving: true });
    await saveAPIDebounced(text);
    this.setState({ saving: false });
  };

}

I also have this lib which may be convenient for your usecase: https://github.com/slorber/react-nested-loader

ghost commented 5 years ago

@slorber In the example you provided, saving would be true 500ms before the saving actually occurs. So in my use case, when I have AwesomeDebouncePromise(searchAPI, 5000); - it becomes way more apparent that it says it is saving a whole 5 seconds before the function is actually run.

My goal would be to have it say it is saving WHEN the function is run, not when the debounce is called upon. The only way I can figure out to do that is with state but I am totally open to other suggestions.

You're library is amazing but this is just one thing I'm trying to wrap my head around

slorber commented 5 years ago

I see the problem.

There is a function "onlyResolvesLast" that is exported.

Didn't try this but maybe you can try doing:

const save = onlyResolvesLast(saveParams => fetch(saveParams));

class SomeComp extends React.Component {
  state = {
    saving: false,
  };

  saveDebounced = AwesomeDebouncePromise (async () => {
    this.setState({ saving: true });
    await save();
    // onlyResolvesLast should ensure that you won't have concurrent requests trying to set saving=false
    this.setState({ saving: false });
  },500);

  onSavePress = () => {
    // optional: maybe reset to saving=false even if there is a current saving still happing in background
    this.setState({ saving: false });
    this.saveDebounced();
  }

}

Do you have in mind a better api that I could implement to support your usecase?

ghost commented 5 years ago

@slorber I'm not sure where you're getting/defining onlyResolvesLast(). This makes sense apart from that!

slorber commented 5 years ago

Hi,

it's exported there but not documented: https://github.com/slorber/awesome-debounce-promise/blob/master/index.js#L10

I'll probably extract this in a separate lib some day

slorber commented 5 years ago

@bgold0 I've exported the fucntion to a separate package. https://github.com/slorber/awesome-only-resolves-last-promise

Have you successfully achieved what you wanted?

slorber commented 5 years ago

Hi,

I'm closing but feel free to reopen if you can provide more details

Also take a look at https://github.com/slorber/react-async-hook/tree/master/src