Dashboard sipadu mbip
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

useStateAsync.js 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { useCallback, useEffect, useRef, useState } from 'react';
  2. /**
  3. * A hook that mirrors `useState` in function and API, expect that setState
  4. * calls return a promise that resolves after the state has been set (in an effect).
  5. *
  6. * This is _similar_ to the second callback in classy setState calls, but fires later.
  7. *
  8. * ```ts
  9. * const [counter, setState] = useStateAsync(1);
  10. *
  11. * const handleIncrement = async () => {
  12. * await setState(2);
  13. * doWorkRequiringCurrentState()
  14. * }
  15. * ```
  16. *
  17. * @param initialState initialize with some state value same as `useState`
  18. */
  19. function useStateAsync(initialState) {
  20. var _useState = useState(initialState),
  21. state = _useState[0],
  22. setState = _useState[1];
  23. var resolvers = useRef([]);
  24. useEffect(function () {
  25. resolvers.current.forEach(function (resolve) {
  26. return resolve(state);
  27. });
  28. resolvers.current.length = 0;
  29. }, [state]);
  30. var setStateAsync = useCallback(function (update) {
  31. return new Promise(function (resolve, reject) {
  32. setState(function (prevState) {
  33. try {
  34. var nextState; // ugly instanceof for typescript
  35. if (update instanceof Function) {
  36. nextState = update(prevState);
  37. } else {
  38. nextState = update;
  39. } // If state does not change, we must resolve the promise because
  40. // react won't re-render and effect will not resolve. If there are already
  41. // resolvers queued, then it should be safe to assume an update will happen
  42. if (!resolvers.current.length && Object.is(nextState, prevState)) {
  43. resolve(nextState);
  44. } else {
  45. resolvers.current.push(resolve);
  46. }
  47. return nextState;
  48. } catch (e) {
  49. reject(e);
  50. throw e;
  51. }
  52. });
  53. });
  54. }, [setState]);
  55. return [state, setStateAsync];
  56. }
  57. export default useStateAsync;