React & TypeScript 上传文件输入错误

React & TypeScript Upload File Input Error

我正在尝试使用 React 和 TypeScript 提交表单,但总是出现错误。

我的终端输出此错误 Type 'File | undefined' is not assignable to type 'string | number | readonly string[] | undefined',如果我尝试上传文件,网站会崩溃并显示此警告和错误。

警告:组件正在将不受控制的输入更改为受控制。这可能是由于值从 undefined 更改为 defined 值引起的,这不应该发生。在组件的生命周期内决定使用受控或非受控输入元素。

未捕获的 DOMException:无法在 'HTMLInputElement' 上设置 'value' 属性:此输入元素接受文件名,该文件名只能以编程方式设置为空细绳。在 HTMLInputElement.set [作为值]

-- 编辑 --

所以在调试了一段时间后我发现如果我只是将一个空字符串传递到值属性然后表单提交并且我的图像/文件被处理并且工作正常。所以问题在于 value 属性的设置,这意味着我需要修复这个错误! Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string. at HTMLInputElement.set [as value]

我有以下输入组件

import React, { useRef } from "react";
import { styled } from "../../../stitches.config";

const Input = styled("input", {
    width: "100%",
    height: "45px",
    background: "$white",
    color: "$black",
    textIndent: "10px",
    border: "1px solid $grey",
    borderRadius: "5px",
    paddingRight: "10px",
});

interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
    onChange: React.ChangeEventHandler<HTMLInputElement>;
}

export default ({ type, name, value, required, onChange }: Props) => {
    const input = useRef<HTMLInputElement>(null);

    return (
        <Input
            type={type}
            name={name}
            value={value}
            ref={input}
            required={required}
            onChange={(e) => onChange(e)}
        />
    );
};

我的表单组件是这样的

interface Props {
    auth: any;
}

interface FormProps {
    title: string;
    intro: string;
    content: string;
    image: File | undefined;
    published_date: string;
}

const Create = ({ auth }: Props) => {
    const { data, setData, processing, post, errors } = useForm<FormProps>({
        title: "",
        intro: "",
        content: "",
        image: undefined,
        published_date: "",
    });

    const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (e.target.files) {
            setData("image", e.target.files[0]);
            console.log(data.image, " image");
        }
    };

    const onSubmit = (e: React.SyntheticEvent) => {
        e.preventDefault();
        post("/admin/blogs/create", {
            preserveScroll: true,
        });
    };

    return (
        <Authenticated auth={auth} css={{ background: "$light" }}>
            <Container css={{ maxWidth: "1200px", py: "100px" }}>
                <Heading size="charlie">Create a post</Heading>
                <Errors errors={errors} />

                <form onSubmit={onSubmit} noValidate>
                   
                    ....

                    <Row>
                        <Label input={"image"} value={"Image"} required={true}>
                            <Input
                                type="file"
                                name="image"
                                value={data.image}
                                required={true}
                                onChange={handleFile}
                            />
                            {errors.image && (
                                <InputError error={errors.image} />
                            )}
                        </Label>
                    </Row>
                    <Row>
                        <Button
                            processing={processing}
                            type={"submit"}
                            color={"primary"}
                        >
                            Publish
                        </Button>
                    </Row>
                </form>
            </Container>
        </Authenticated>
    );
};

export default Create;

由于一个文件输入<input type="file" />的值是read-only,它只能是一个非受控元素,也就是说它不带valueprop。 docs

在您的自定义输入元素中,您可能需要在传递 value 属性之前检查 type