首页 > 解决方案 > 尝试在 React 组件中的表单中上传 PDF 文件,但在使用 setFormData 时获取 {}

问题描述

我正在尝试创建一个表单来响应文件上传功能。我编写了一个handleFileUpload函数,当用户选择需要上传的文件时触发该函数。在我使用的情况下,该文件已正确记录在控制台中e.target.files[0],但是当我尝试将文件设置为 state 或formData时,formData 中的文件值始终为 {}。任何形式的帮助将不胜感激。

我尝试过使用表单encType='multipart/form-data',但无济于事。我什至尝试使用 useState 将文件存储在单独的状态,但是当我尝试使用 setState 执行setState时再次得到空括号e.target.files[0]

这是我的组件的代码,我在其中获取需要使用表单中的输入标签上传的用户文件。

const AddNewContract = ({createNewContract}) => {
    const [formData, setFormData] = useState({
        file: null
      });

      const {
        file
    } = formData

    const handleFileUpload = e => {
      e.preventDefault();
      const temp_file = e.target.files[0];
      console.log(temp_file);

      setFormData({ ...formData, file: temp_file });
    }


    return (
        <Fragment>
            <Container >
            <form className='form' onSubmit={args => onSubmit(args)} >
            <p className='lead'>
             <i className='fas fa-user' /> Enter the new contract details.
            </p>

        <div className='form-group'>
        <label htmlFor="clientName">Upload contract PDF </label>
          <input type='file' name='file' onChange={args => handleFileUpload(args)} />
        </div>

        <input type='submit' className='btn btn-primary my-1' value='Add Contract' />
      </form>
      </Container>
      <div>
        {JSON.stringify(formData)}
      </div>
        </Fragment>


    )
}

AddNewContract.propTypes = {
    createNewContract: PropTypes.func.isRequired
}

export default connect(null, {createNewContract})(withRouter(AddNewContract));

我希望formData状态将文件作为文件的值,但我得到{"file":{}}. 该console.log(temp_file)命令给了我:

文件 {name: "Resume.pdf", lastModified: 1571412334151, lastModifiedDate: Fri Oct 18 2019 11:25:34 GMT-0400 (Eastern Daylight Time), webkitRelativePath: "", size: 128128, ...}

这是整个文件内容,正是我想要存储在我的 state 或formData中的内容,但由于某种原因它不起作用。请帮我在这里找到问题。

标签: javascriptreactjsformsfile-uploadreact-state

解决方案


因此,这里发生的情况是,当您打印 formData 时, {file:{}}即使您选择了一个文件,您也会变空,因为该文件不是 JSON 对象,因此执行 JSON.Stringify() 不会打印文件的键。

相反,我建议如果您想打印 formData 的内容,请使用此功能。

const getFormDataContent = (formData = {}) => {
    const { file } = formData;
    let keys = Object.keys(formData);
    keys = keys.filter(key => key !== "file");
    const data = {
      lastModified: file.lastModified,
      lastModifiedDate: file.lastModifiedDate,
      name: file.name,
      size: file.size,
      type: file.type
    };
    const fileData = { file: data };
    keys.forEach(key => {
      fileData[key] = formData[key];
    });
    return fileData;
  };

然后像这样使用这个 JSON.Stringify 打印它

<div>{JSON.stringify(getFormDataContent(formData))}</div>


推荐阅读