Home > Back-end >  react dropzone with image preview written typescript
react dropzone with image preview written typescript

Time:01-23

I am new to front end and typescript. I would like to create the ability to preview drag and drop files using react-dropzone, an example javascript version exists but does not work in typescript. I have run the following code.

import { useEffect, useCallback, useMemo, useState } from 'react';
import { useDropzone, FileWithPath, DropzoneState  } from 'react-dropzone';

const styleDiv = {
  margin: "1%"
}

const style = {
  width: 200,
  height: 150,
  border: "1px dotted #888"
};

function App() {
  const [files, setFiles] = useState([]);
  const {getRootProps, getInputProps} = useDropzone({
    accept: {
      'image/*': []
    },
    onDrop: acceptedFiles => {
      setFiles(acceptedFiles.map(file => Object.assign(file, {
        preview: URL.createObjectURL(file)
      })));
    }
  });

  const thumbs = files.map(file => (
    <div key={file.name}>
      <div>
        <img
          src={file.preview}
          // Revoke data uri after image is loaded
          onl oad={() => { URL.revokeObjectURL(file.preview) }}
        />
      </div>
    </div>
  ));

  useEffect(() => {
    // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
    return () => files.forEach(file => URL.revokeObjectURL(file.preview));
  }, []);

  return (
    <section className="container">
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <aside>
        {thumbs}
      </aside>
    </section>
  );
}

export default App;

I received the following error

Compiled with warnings.

[eslint]
src/App.tsx
  Line 1:21:  'useCallback' is defined but never used                                                                    @typescript-eslint/no-unused-vars
  Line 1:34:  'useMemo' is defined but never used                                                                        @typescript-eslint/no-unused-vars
  Line 2:23:  'FileWithPath' is defined but never used                                                                   @typescript-eslint/no-unused-vars
  Line 2:37:  'DropzoneState' is defined but never used                                                                  @typescript-eslint/no-unused-vars
  Line 4:7:   'styleDiv' is assigned a value but never used                                                              @typescript-eslint/no-unused-vars
  Line 8:7:   'style' is assigned a value but never used                                                                 @typescript-eslint/no-unused-vars
  Line 30:9:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text
  Line 42:6:  React Hook useEffect has a missing dependency: 'files'. Either include it or remove the dependency array   react-hooks/exhaustive-deps

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

WARNING in [eslint]
src/App.tsx
  Line 1:21:  'useCallback' is defined but never used                                                                    @typescript-eslint/no-unused-vars
  Line 1:34:  'useMemo' is defined but never used                                                                        @typescript-eslint/no-unused-vars
  Line 2:23:  'FileWithPath' is defined but never used                                                                   @typescript-eslint/no-unused-vars
  Line 2:37:  'DropzoneState' is defined but never used                                                                  @typescript-eslint/no-unused-vars
  Line 4:7:   'styleDiv' is assigned a value but never used                                                              @typescript-eslint/no-unused-vars
  Line 8:7:   'style' is assigned a value but never used                                                                 @typescript-eslint/no-unused-vars
  Line 30:9:  img elements must have an alt prop, either with meaningful text, or an empty string for decorative images  jsx-a11y/alt-text
  Line 42:6:  React Hook useEffect has a missing dependency: 'files'. Either include it or remove the dependency array   react-hooks/exhaustive-deps

webpack compiled with 1 warning
ERROR in src/App.tsx:21:16
TS2345: Argument of type '(T & { preview: string; })[]' is not assignable to parameter of type 'SetStateAction<never[]>'.
  Type '(T & { preview: string; })[]' is not assignable to type 'never[]'.
    Type 'T & { preview: string; }' is not assignable to type 'never'.
    19 |     },
    20 |     onDrop: acceptedFiles => {
  > 21 |       setFiles(acceptedFiles.map(file => Object.assign(file, {
       |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  > 22 |         preview: URL.createObjectURL(file)
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  > 23 |       })));
       | ^^^^^^^^^^
    24 |     }
    25 |   });
    26 |

ERROR in src/App.tsx:28:20
TS2339: Property 'name' does not exist on type 'never'.
    26 |
    27 |   const thumbs = files.map(file => (
  > 28 |     <div key={file.name}>
       |                    ^^^^
    29 |       <div>
    30 |         <img
    31 |           src={file.preview}

ERROR in src/App.tsx:31:21
TS2339: Property 'preview' does not exist on type 'never'.
    29 |       <div>
    30 |         <img
  > 31 |           src={file.preview}
       |                     ^^^^^^^
    32 |           // Revoke data uri after image is loaded
    33 |           onl oad={() => { URL.revokeObjectURL(file.preview) }}
    34 |         />

ERROR in src/App.tsx:33:52
TS2339: Property 'preview' does not exist on type 'never'.
    31 |           src={file.preview}
    32 |           // Revoke data uri after image is loaded
  > 33 |           onl oad={() => { URL.revokeObjectURL(file.preview) }}
       |                                                    ^^^^^^^
    34 |         />
    35 |       </div>
    36 |     </div>

ERROR in src/App.tsx:41:65
TS2339: Property 'preview' does not exist on type 'never'.
    39 |   useEffect(() => {
    40 |     // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
  > 41 |     return () => files.forEach(file => URL.revokeObjectURL(file.preview));
       |                                                                 ^^^^^^^
    42 |   }, []);
    43 |
    44 |   return (

I think the problem is that you are trying to access an object that does not exist, but I don't know how to solve it. I would like to know how to solve this problem.

CodePudding user response:

Modify your files state like this:

const [files, setFiles] = useState<(File & {preview:string})[]>([]);
  • Related