Свойство «файлы» отсутствует в типе «EventTarget & HTMLTextAreaElement»

Я пытаюсь вызвать метод в React TypeScript для события onChange поля ввода MUI.

К сожалению, я получаю следующую ошибку на onChange:

Type '(event: { target: { files: any[]; }; }) => void' is not assignable to type 'ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>'. Types of parameters 'event' and 'event' are incompatible. Type 'ChangeEvent<HTMLTextAreaElement | HTMLInputElement>' is not assignable to type '{ target: { files: any[]; }; }'. Types of property 'target' are incompatible. Type 'EventTarget & (HTMLTextAreaElement | HTMLInputElement)' is not assignable to type '{ files: any[]; }'. Property 'files' is missing in type 'EventTarget & HTMLTextAreaElement' but required in type '{ files: any[]; }'.

Я пытаюсь получить доступ к состоянию, а затем вызвать метод с помощью onChange.

Также важно для вас, ребята, что у меня нет большого опыта в загрузке и сохранении файлов в React TypeScript с моим API в JS, он работает, но в TypeScript нет. Я также прошел 100 руководств, но мне ничего не помогло.

import axios from "axios";
import React from "react";
import { Input } from "@mui/material";
// export class FileUpload extends Component {
const FileUpload: React.FC = () => {
    
    const [selectedFile] = React.useState<Blob>(new Blob);
    // const [users] = React.useState<Blob | string>("");


    function onFileChange(event: { target: { files: any[]; }; }): void {
    // function onFileChange(event: { target: { files: any[]; }; }): void {
        React.useState({ selectedFile: event.target.files[0] });
    }

    // On file upload (click the upload button)
    async function onFileUpload() {
        // Create an object of formData
        const formData = new FormData();
        // Update the formData object
        formData.append(
            "File",
            selectedFile,
            selectedFile.text.toString()
        );
        // Details of the uploaded file
        console.info(selectedFile);
        // Request made to the backend api
        // Send formData object
        try {
            const responseData = await axios.post("https://localhost:7047/File/Upload", formData);
            console.info(responseData);
        } catch (ex) {
            console.info(ex);
        }
    }

    return (
        <div>
            <Input onChange = {onFileChange} />
            <Input type = "button" value = "upload" onClick = {onFileUpload} />
        </div>
    );
};
export default FileUpload;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пользовательский интерфейс материала объявляет тип реквизита onChange как:

onChange?: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement> | undefined

Вы можете обнаружить это, наведя указатель мыши на onChange, и вы увидите сообщаемый тип.

Это означает, что он обрабатывает текстовую область или тег ввода. Это означает, что ваш обработчик событий должен обрабатывать и то, и другое. И проблема здесь в том, что только HTMLInputElement с типом file будет иметь свойство files.

И в вашем коде, если бы не было files, он бы рухнул.


Итак, сначала вам нужно правильно объявить тип события:

function onFileChange(event: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>): void {
  //...
}

Затем вам нужно убедиться, что свойство files существует, прежде чем использовать его.

function onFileChange(event: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>): void {
    if ('files' in event.target) {
        React.useState({ selectedFile: event.target.files?.[0] });
    } 
}

Теперь вы получаете доступ только к files, если он существует, и вы используете ?. только для детализации, если это не null или undefined.

Площадка без ошибок типа

Спасибо за совет, я так все отредактировал. Теперь я получаю следующую ошибку, с которой не могу справиться... React Hook "React.useState" вызывается условно. React Hooks должны вызываться в одном и том же порядке при рендеринге каждого компонента. Это происходит в функции onFileChange, вероятно, что-то связанное с :void? В строке React.useState({ selectedFile: event.target и т. д.) происходит сбой.

Noah 17.03.2022 10:54

но в целом вы правы, потому что другая ошибка, которую я получил, не имеет ничего общего с этой, поэтому я отмечу ее как правильную. Спасибо!

Noah 27.03.2022 09:59

Другие вопросы по теме