Загрузка нескольких изображений с помощью React

Я хотел бы сначала загрузить несколько изображений, предварительно просмотрев их, а затем отправив их для отправки. Я столкнулся с этим: TypeError: Cannot read property 'files' of null. Это также позволяет мне загружать только одно изображение.

  • Я создал files: [] как средство для монтирования изображений для просмотра перед отправкой.
  • Пытался создать интерфейс files: File[] = file, а затем объявить его в состоянии, но получил другую ошибку, которая file does not exist on type {}
import * as React from "react"

class ImageUpload extends React.Component {
  state: {
    files: []
  }

  fileSelectedHandler = (file: any) => {
    let addedFiles = this.state.files.concat(file)
    this.setState({ files: addedFiles })
    console.info("upload file " + file.name)
  }

  render() {
    return (
      < form >
        <div>
          <h2>Upload images</h2>
        </div>
        <h3>Images</h3>
        <input type = "file" onChange = {this.fileSelectedHandler} />
      </form>
    )
  }
}

export default ImageUpload

Я ожидаю, что это позволит мне выбрать несколько изображений и сохранить их в массиве, прежде чем отправлять их в виде пакета. Это даже правильный способ сделать это? Любая обратная связь очень ценится.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
3
0
27 073
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
  1. Чтобы исправить ошибку TypeError: Cannot read property 'files' of null. вам нужно изменить декларацию state
state = {
   files: []
}
  1. Если вы хотите иметь возможность выбрать несколько файлов, вы можете использовать опцию multiple
<input type = "file" multiple onChange = {this.fileSelectedHandler} />

Или, если вы хотите выбрать изображение одно за другим, ваша реализация должна работать, просто исправьте объявление state и используйте e.target.files, чтобы получить выбранный файл.

class ImageUpload extends React.Component {
  state = {
    files: []
  }

  fileSelectedHandler = (e) => {
    this.setState({ files: [...this.state.files, ...e.target.files] })
  }

  render() {
    return (
      <form>
        <div><h2>Upload images</h2></div>
        <h3>Images</h3>
        <input type = "file" multiple onChange = {this.fileSelectedHandler} />
      </form>
    )
  }
}


ReactDOM.render(<ImageUpload />, document.getElementById('app'))
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id = "app"></div>

Спасибо, это работает довольно хорошо. Также хотел бы указать на ошибку, которую я получил, потому что я использовал: вместо = при объявлении своего состояния. Упс.

Prozak 24.04.2019 16:24

Форма ручки Исходные данные:

const initialProducts = {
name: "",   
featured_image: "", //for single image
slider_images: [], // (array of strings)   
};

использование состояния

const [products, setProducts] = useState(initialProducts);

Функция: обработка полей ввода

const handleInput = (e) => {
let updateValues = { ...products };
updateValues[e.target.name] = e.target.value;
setProducts(updateValues);
console.info("Update input values", updateValues);
};

Функция: обработка нескольких изображений

 const handleSliderImages = (e) => {
  if (e.target.files) {
  setProducts({ ...products, slider_images: [...e.target.files] });
  }
  console.info("Update slider images", products);
};

FormGroup для полей ввода

<FormGroup className = "my-3">
  <Label for = "name">Name</Label>
   <Field
    name = "name"
    id = "name"
    onChange = {handleInput}
    value = {products.name}
   />
</FormGroup>

FormGroup для одного изображения

 <FormGroup className = "my-3">
  <Label for = "featured_image">Featured Image</Label>
  <CustomInput
   type = "file"
   id = "featured_image"
   name = "featured_image"
   onChange = {handleInput}
   value = {products.featured_image}                  
  />               
 </FormGroup>

FormGroup для нескольких изображений

<FormGroup className = "my-3">
 <Label for = "slider_images">Slider Images</Label>
 <CustomInput
 multiple
 type = "file"
 id = "slider_images"
 name = "slider_images"
 onChange = {handleSliderImages}
 />                
</FormGroup>

Вы можете решить эту проблему, используя несколько полей ввода. Вы можете отслеживать поле ввода, используемое для загрузки файла, используя их уникальный «ID». Пожалуйста, взгляните на код, которым я поделился.

Поле ввода

обработчик onChange

обработчик файлов на основе идентификатора

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