首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与TypeScript反应的其他表单的可重用输入组件

与TypeScript反应的其他表单的可重用输入组件
EN

Stack Overflow用户
提问于 2022-05-24 20:47:50
回答 1查看 405关注 0票数 -2

我刚得到一个独立的部件。这是一个下拉区域字段,我们正在使用它来获取用户文件。这个下拉区域组件是一个具有自己的onsubmit事件的表单。

我们正在应用程序中进行一些重构,在一些场景中,我们需要在具有其他类型字段(例如单选按钮或文本字段)的其他形式中重用这个下拉区域组件。因为我的下拉区域有它自己的onsubmit事件和它自己的父表单标签,所以我显然不能在另一个表单中重用它。我不能在表单中添加表单,所以我试图找到一种最好的方法来创建一个可以与其他字段一起在任何现有表单中重用的单下拉区域字段。

小问题是,我的组件已经有了自己的onsubmit事件,当按submit按钮时,它使用createFile钩子将文件上传到服务器,因此我不知道如何制作另一个下拉区域组件,该组件可以添加到任何现有表单中,并将自动将组件中删除的文件上传到服务器。

这是构成部分:

代码语言:javascript
复制
import 'twin.macro';
import React, { useState } from 'react';
import Dropzone from 'react-dropzone';
import { ErrorBoundary } from 'react-error-boundary';

import { createFile } from '@api/file';
import { ALLOWED_MIMES } from '@utility/constants';
import prettyBytes from '@utility/prettyBytes';
import Button from '@components/Button';
import ErrorFallback from '@components/ErrorFallback';
import type { User } from '@types';
import PreparedFiles from './PreparedFiles';
import UploadIcon from './UploadIcon';

const SingleDropzone: React.FC<{
  user: User;
  slug?: string;
  uploadComplete?: () => void;
}> = ({ user, slug, uploadComplete }) => {
  const [queuedFiles, setQueuedFiles] = useState<File[]>([]);
  const [uploading, setUploading] = useState(false);

  const onDrop = (acceptedFiles: File[]) => setQueuedFiles(acceptedFiles);

  const resetQueuedFiles = () => setQueuedFiles([]);

  const onSubmit = (event: React.FormEvent) => {
    event.preventDefault();

    const promises = queuedFiles.map((file: File) => {
      setUploading(true);

      return createFile({
        user_id: user.id,
        name: file.name,
        upload: file,
        // will use the slug or the default folder
        folder_slug: slug || null,
      });
    });

    Promise.all(promises)
      .then(resetQueuedFiles)
      .catch((error) => {
        // trigger error boundary
        throw new Error(error);
      })
      .finally(() => {
        setUploading(false);
        if (uploadComplete) {
          uploadComplete();
        }
      });

    return false;
  };

  return (
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <form
        encType="multipart/form-data"
        method="post"
        action="/api/files"
        onSubmit={onSubmit}
      >
        {queuedFiles.length > 0 ? (
          <PreparedFiles files={queuedFiles} />
        ) : (
          <Dropzone accept={ALLOWED_MIMES} onDrop={onDrop}>
            {({ getRootProps, getInputProps }) => (
              <section tw="flex items-center justify-center rounded border-2 border-dashed my-5">
                <div
                  tw="flex flex-col items-center space-y-2 w-full p-5"
                  {...getRootProps()}
                >
                  <input {...getInputProps()} />
                  <div tw="w-9 h-9">
                    <UploadIcon />
                  </div>
                  <p tw="type-1450 text-gray-600">
                    <span tw="text-indigo-600">Upload a file</span> or drag and
                    drop
                  </p>
                  <p tw="type-1240 text-gray-500">
                    PNG, JPG, PDF, Doc up to 20MB
                  </p>
                </div>
              </section>
            )}
          </Dropzone>
        )}
        {queuedFiles.length > 0 ? (
          <div tw="mt-5 w-full flex items-center justify-end space-x-3">
            {uploading ? null : (
              <Button
                type="button"
                styleType="none"
                tw="underline"
                onClick={resetQueuedFiles}
              >
                Cancel
              </Button>
            )}
            {uploading ? (
              <Button type="button" styleType="primary" tw="opacity-70">
                Uploading...
              </Button>
            ) : (
              <Button type="submit" styleType="primary">
                Upload
              </Button>
            )}
          </div>
        ) : null}
      </form>
    </ErrorBoundary>
  );
};

export default SingleDropzone;
EN

回答 1

Stack Overflow用户

发布于 2022-05-24 21:34:03

如果你正确地理解了你,我就不会百分之百。但是,如果您有一个已经存在的组件,您希望能够使用不同的值进行重用,我将研究一下道具。应该很简单。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72369285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档