kqito / use-tus

React hooks for resumable file uploads using tus
https://kqito.github.io/use-tus/?path=/story/usetus--basic
MIT License
104 stars 8 forks source link
hooks react react-hooks tus tus-js-client

use-tus

React hooks for resumable file uploads using tus.

Build status Npm version License

Features

Demo

You can try the use-tus demo.

Installation

You can install the package from npm.

npm install use-tus tus-js-client

or

yarn add use-tus tus-js-client

Usage

We can use useTus as following.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload, isSuccess, error, remove } = useTus();

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      setUpload(file, {
        endpoint: 'https://tusd.tusdemo.net/files/',
        metadata: {
          filename: file.name,
          filetype: file.type,
        },
      });
    },
    [setUpload]
  );

  const handleStart = useCallback(() => {
    if (!upload) {
      return;
    }

    // Start to upload the file.
    upload.start();
  }, [upload]);

  return (
    <div>
      <input type="file" onChange={handleSetUpload} />
      <button type="button" onClick={handleStart}>
        Upload
      </button>
    </div>
  );
};

API

useTus hooks

const { upload, setUpload, isSuccess, isAborted, isUploading, error, remove } = useTus({ autoAbort, autoStart, uploadOptions, Upload });

useTus is a hooks that creates an object to perform Resumable file upload.

Arguments

About uploadOptions

This option extends the UploadOptions provided by tus-js-client, but it has been extended so that every callback can receive the upload instance as the final argument.

For detail type information of UploadOptions, please see here.

e.g.

setUplaod(file, {
  onSuccess: (upload) => {
    console.log(upload.url)
  },
  onError: (error, upload) => {
    console.log(error)

    setTimeout(() => {
      upload.start()
    }, 1000)
  }
})

Returns

useTusStore hooks

const { upload, setUpload, isSuccess, isAborted, isUploading, error, remove } = useTusStore(cacheKey, { autoAbort, autoStart, uploadOptions, Upload  });

useTusStore is a hooks that creates an object for resumable file upload and stores it in a context.

This hooks is useful when you want to handle uploads across pages or components.

Note that using useTusStore hooks, the TusClientProvider must be specified as the parent or higher element.

Arguments

Returns

Returns

TusClientProvider

() => (
  <TusClientProvider defaultOptions={defaultOptions}>
    {children}
  </TusClientProvider>
)

TusClientProvider is the provider that stores the Upload with useTusStore hooks.

Props

useTusClient

const { state, removeUpload, reset } = useTusClient();

useTusClient is a hooks that can be used to retrieve and reset the state of a TusClientProvider.

Returns

Examples

The following are some example of how to use use-tus.

Uploading a file

The setUpload and upload.start functions can be used to perform resumable file uploads.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload } = useTus();

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      setUpload(file, {
        endpoint: 'https://tusd.tusdemo.net/files/',
        metadata: {
          filename: file.name,
          filetype: file.type,
        },
      });
    },
    [setUpload]
  );

  const handleStart = useCallback(() => {
    if (!upload) {
      return;
    }

    // Start upload the file.
    upload.start();
  }, [upload]);

  return (
    <div>
      <input type="file" onChange={handleSetUpload} />
      <button type="button" onClick={handleStart}>
        Upload
      </button>
    </div>
  );
};

It is also possible to automatically upload files after setUpload by specifying the autoStart option.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload } = useTus({ autoStart: true });

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      setUpload(file, {
        endpoint: 'https://tusd.tusdemo.net/files/',
        metadata: {
          filename: file.name,
          filetype: file.type,
        },
      });
    },
    [setUpload]
  );
  return (
    <input type="file" onChange={handleSetUpload} />
  );
};

Aborting a file upload

You can abort the upload by using the upload.abort function.

import { useTus } from 'use-tus'

const Aborter = () => {
  const { upload } = useTus();

  const handleAbort = useCallback(() => {
    if (!upload) {
      return;
    }

    upload.abort();
  }, [upload]);

  return (
    <div>
      <button type="button" onClick={handleAbort}>
        Abort
      </button>
    </div>
  );
};

You can also specify the autoAbort option to automatically stop uploads when unmounting hooks.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload } = useTus({ autoAbort: true });

  // omitted...
};

Default options of upload

You can specify default options in the defaultOptions props of the TusClientProvider.

import { useTusStore, DefaultOptions, TusClientProvider } from 'use-tus'

const defaultOptions: DefaultOptions = (contents) => {
  const file = contents instanceof File ? contents : undefined;

  return {
    endpoint: 'https://tusd.tusdemo.net/files/',
    metadata: file
      ? {
          filename: file.name,
          filetype: file.type,
        }
      : undefined,
  };
};

const App = () => (
  <TusClientProvider defaultOptions={defaultOptions}>
    <Uploader />
  </TusClientProvider>
);

const Uploader = () => {
  const { setUpload } = useTusStore('cacheKey', { autoStart: true });

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      // You no longer need to specify the options associated with upload.
      // If specified, it will override defaultOptions.
      setUpload(file);
    },
    [setUpload]
  );

  return (
    <div>
      <input type="file" onChange={handleSetUpload} />
    </div>
  );
};

Specify upload key

If you specify cacheKey as an argument to useTusStore, you can get the upload associated with it. This is useful for cross-page file uploads.

const SelectFileComponent = (file: File) => {
  // Create upload accosiated with 'upload-thumbnail' key
  const { setUpload } = useTusStore('upload-thumbnail')

  setUpload(file)
}

const UploadFileComponent = () => {
  const { upload } = useTusStore('upload-thumbnail')

  upload.start()
}

License

MIT © kqito