Typescript 和 React with File Upload(打字)

Posted

技术标签:

【中文标题】Typescript 和 React with File Upload(打字)【英文标题】:Typescript and React with File Upload (typing) 【发布时间】:2021-02-05 19:40:24 【问题描述】:

我刚开始使用 TypeScript,所以请记住。我正在尝试在 React/TS 中实现一个简单的文件上传。一般来说,我认为我不了解如何初始化对象,例如在 useState 中,并正确处理可能性。例如,考虑以下代码,当用户单击“上传”按钮时我正在运行一个函数,我尝试从状态中读取文件并将其放入 formData 以将其发送到我的 api 端点):


const [fileSelected, setFileSelected] = React.useState<File>() // also tried <string | Blob>

const handleImageChange = function (e: React.ChangeEvent<htmlInputElement>) 
    const fileList = e.target.files;

    if (!fileList) return;
    
    setFileSelected(fileList[0]);
  ;

   const uploadFile = function (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) 
    const formData = new FormData();
    formData.append("image", fileSelected, fileSelected.name);

     // line above ^ gives me the error below
  ;

'string | 类型的参数斑点 |未定义'不是 可分配给 'string | 类型的参数斑点'。 类型“未定义”不可分配给类型“字符串 | Blob'.ts(2345)

你应该如何在 useState 中初始化你的对象?如果你不初始化,就像这里一样,你是否必须继续检查 null 才能让编译器满意?我刚刚在 UploadFile 中添加了一个检查,以查看 fileSelected 是否为空。但后来我不得不再次引用 fileSelected.name。

那么对于对象,尤其是像这种文件类型的对象,你应该如何处理初始化它?而且,一般来说,如何处理对象类型?

没关系,但这是标记部分:

        <Container className=classes.container>
          <label htmlFor="photo">
            <input
              accept="image/*"
              style= display: "none" 
              id="photo"
              name="photo"
              type="file"
              multiple=false
              onChange=handleImageChange
            />

            <Button
              className=classes.buttons
              component="span"
              variant="contained"
              onClick=uploadFile
            >
              Choose Picture
            </Button>
          </label>
        </Container>

【问题讨论】:

【参考方案1】:

当您在没有设置初始/默认值的情况下调用useState 时,除了预期的类型外,该类型还将包括undefined。在这里,您使用了通用的 &lt;File&gt; 来告诉 useState 期望什么类型。但是因为你没有设置值就发起了,fileSelected的类型变成了File | undefined

这很好,因为它准确地表示了状态中并不总是存在File 对象的现实。但这确实意味着我们必须在使用之前检查fileSelected 的值。只需添加一个if 语句,您的formData.append() 调用在运行时或在打字稿编译器中不会有任何问题。接口File 扩展了Blob,因此在我们排除了undefined 的可能性后,将其分配给string | Blob 没有问题。

const uploadFile = function (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) 
    if (fileSelected) 
        const formData = new FormData();
        formData.append("image", fileSelected, fileSelected.name);
    
;

Playground Link

【讨论】:

在我发布此内容后,我确实输入了“|undefined”,所以现在我考虑了一下,这是有道理的。它期望它是一个文件,期间。所以一个文件|未定义,然后检查非常有意义。再次感谢你:) 感谢游乐场!我不知道这允许你使用 React。并且看到发出的 javascript 非常酷。

以上是关于Typescript 和 React with File Upload(打字)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React with Typescript 中使用和指定通用 Hooks?

Jest Manual Mocks with React 和 Typescript:模拟 ES6 类依赖

[React Native] Up & Running with React Native & TypeScript

tsdoc-param-tag-with-invalid-name:@param 块后面应该跟一个有效的参数名称(TypeScript ESLint 和 React)

React Typescript with hooks:最大更新深度超出错误

Typescript with React - 在通用组件类上使用 HOC