3

我在 React 中使用 Formik 作为我的表单。一切都很好,但对于文件输入。

用户必须能够上传简历。Formik 中的 {values.cv} 确实表明输入中有一个值。但是,当我将它发送到我的 Laravel 后端时,我得到一个空数组。

我希望能够将文件存储在我的数据库中。任何帮助,将不胜感激。

Formik 文件输入:

<label className="btn btn-info" htmlFor="cv">
    <input id="cv" name="cv" style={{display: 'none'}} type="file" onChange={(event) => {
     setFieldValue("cv", event.currentTarget.files[0]);
                                    }} />                   
   </label>

cv 输入默认值为:''

这是 {values.cv} 中的内容 这是它的 console.log

在我的 Laravel 后端,我返回 $request 并且 React 正在记录它。这就是我当时看到的。

简历 : []

这是我的控制台的图片

4

2 回答 2

3

根据这篇文章

<input id="file" name="file" type="file" onChange={(event) => { setFieldValue("file", event.currentTarget.files[0]); }} />

然后你可以访问所有的东西......

JSON.stringify({ 
  fileName: values.file.name, 
  type: values.file.type,
  size: `${values.file.size} bytes`
}, null, 2);
于 2019-03-03T17:32:55.633 回答
3

Formik 不处理文件上传,但这里提供了一个 hack https://github.com/jaredpalmer/formik/issues/45

import * as React from 'react';

import { AxiosRequestConfig } from 'axios';
import Image from 'components/Image';
import { Progress } from 'components/Progress';
import ToasterInstance from '../Toast/ToasterInstance';
import { axios } from 'api/axios.config';
import { toApiError } from 'utils/api';

export interface MediaUploadProps {
  id: string;
  slug: string;
  value: string;
  onChange: (field: string, mediaId: string) => void;
}

export interface MediaUploadState {
  progress: number;
  file?: File;
  error?: string;
}

export class MediaUpload extends React.Component<
  MediaUploadProps,
  MediaUploadState
> {
  state: MediaUploadState = { progress: -1 };

  handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files) {
      return;
    }
    let file = e.target.files[0];
    this.setState({ file: file });

    let data = new FormData();
    data.append('file', file);

    let config: AxiosRequestConfig = {
      onUploadProgress: (p: any) => {
        this.setState({ progress: Math.round(p.loaded * 100 / p.total) });
      },
    };

    this.setState({ error: undefined, progress: 0 });

    axios.post('/v1/media?slug=' + this.props.slug, data, config).then(
      res => {
        this.setState({ error: undefined, progress: -1 });
        this.props.onChange(this.props.id, res.data.path);
      },
      err => {
        const message = toApiError(err);
        this.setState({ error: message, progress: -1 });
        ToasterInstance.show({
          message,
          iconName: 'danger',
          intent: 'danger',
        });
      }
    );
  }

  handleRemoveImage = () => {
    this.props.onChange(this.props.id, '');
  }

  render() {
    return (
      <div>
        <div>
          {this.props.value !== '' &&
            this.state.progress === -1 &&
            <Image path={this.props.value} size="lg" />}
          <div style={{ maxWidth: 144 }}>
            {this.state.progress > -1 &&
              <Progress percentage={this.state.progress} />}
          </div>
          {this.props.value &&
            <a
              style={{ marginTop: -40 }}
              className="button button--negative button--small button--secondary"
              role="button"
              onClick={this.handleRemoveImage}
            >
              Remove
            </a>}
    </div>
    <div style={{ marginTop: 10 }}>
      <label className="button button--purple button--secondary">
        Upload new picture
        <input
          className="visually-hidden"
          type="file"
          onChange={this.handleFileChange}
        />

      </label>
    </div>

  </div>
);
  }
}
于 2018-09-19T07:06:13.010 回答