2.2.0 • Published 3 years ago

use-defer v2.2.0

Weekly downloads
23
License
MIT
Repository
github
Last release
3 years ago

use-defer

Simplify work with async functions with memoization and state

NPM JavaScript Style Guide

Install

npm install --save use-defer

Usage

import * as React from 'react'

import useDefer, { Status } from 'use-defer'
// Or: import { useDefer, Status } from 'use-defer'

const Example = () => {
  const {
    execute, // Callback for the [asyncFunction] with the same arguments list and result
    status,  // One of: Status.IDLE - no request, Status.PENDING - waiting for results, Status.SUCCESS & Status.ERROR
    value,   // Result of the last request
    error,   // Error thrown during the execution of the last request
  } = useDefer(
    asyncFunction, // The function that returns a [Promise] instance
    [],            // Optional list of [React.DependencyList] type to update [asyncFunction]
    [],            // Optional arguments list. The [asyncFunction] will be called immediately if this is set
  );

  // ...
};

Examples

Using it for a single async function

Source code

const generateNumber = max => new Promise((resolve, reject) => {
  if (max > 0) setTimeout(resolve, 2e3, Math.round(Math.random() * max));
  else setTimeout(reject, 2e3, 'Max value must be greater than zero');
});

const defaultMax = 100;

const SingleFunctionExample = () => {
  const [max, setMax] = React.useState('');

  const { value, error, status } = useDefer(
    generateNumber,           // Async function that returns promise
    [max],                    // Dependencies
    [max ? +max : defaultMax] // Initial arguments
  );

  return (
    <div>
      <div>
        <input
          type="number"
          value={max}
          placeholder={defaultMax.toString()}
          onChange={e => setMax(e.target.value)}
        />
        {status === 'pending' ? <span>processing </span> : null}
      </div>
      {value !== undefined ? <div>Last result: {value}</div> : null}
      {error ? <div>Error: {error}</div> : null}
    </div>
  );
};

Create a model hook with auto reloading

Source code

const useResources = () => {
  const { execute: reload, value: resources, status } = useDefer(api.get, [], []);
  const { execute: create } = useDefer(resource => api.post(resource).then(reload));
  const { execute: remove } = useDefer(id => api.delete(id).then(reload));

  return { resources, status, create, remove };
};

const MultipleFunctionsExample = () => {
  const resourceLabelRef = useRef(null);
  const { resources, status, create, remove } = useResources();

  const onSubmit = e => {
    e.preventDefault();
    create({ label: resourceLabelRef.current.value });
    resourceLabelRef.current.value = '';
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <input type="text" ref={resourceLabelRef} required />
        <input type="submit" value="Add" />
      </form>

      {!resources && status === 'pending' ? <p>Loading...</p> : null}

      {resources
        ? <ol>
          {resources.map(res => (
            <li key={res.id}>
              {res.label}
              {' '}
              <input type="button" onClick={() => remove(res.id)} value="remove" />
            </li>
          ))}
        </ol>
        : null
      }
    </div>
  );
};

License

MIT © termosa


This hook is created using create-react-hook.

2.2.0

3 years ago

2.1.0

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.0.0

3 years ago