用React上传多张图片

时间:2019-04-24 13:27:28

标签: reactjs typescript

我想先上传多张图片,然后预览然后提交以发送出去。我遇到了这个问题: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.log("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

我希望它可以让我选择多个图像并将它们存储在数组中,然后再批量发送。这是正确的方法吗?任何反馈都将不胜感激。

3 个答案:

答案 0 :(得分:1)

  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>

答案 1 :(得分:0)

处理表单 初始数据:

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.log("Update input values", updateValues);
};

功能:处理多张图片

 const handleSliderImages = (e) => {
  if (e.target.files) {
  setProducts({ ...products, slider_images: [...e.target.files] });
  }
  console.log("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 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 className="my-3">
 <Label for="slider_images">Slider Images</Label>
 <CustomInput
 multiple
 type="file"
 id="slider_images"
 name="slider_images"
 onChange={handleSliderImages}
 />                
</FormGroup>

答案 2 :(得分:0)

您可以通过多个输入字段来解决此问题。您可以使用其唯一的“ID”跟踪用于上传文件的输入字段。请看一下我分享的代码。

Input field

onChange handler

file handler based on id