如何使用 redux-form 库从 react-dropzone 插件中获取 base64

How to get base64 out of react-dropzone plugin with redux-form library

我正在开发一个集成了 react-dropzone integrated within redux-form 库的项目。 目前,当我将图像放入拖放区并通过 API 发送时,传递的有效负载如下:

{
    "preview": "blob:localhost:3000/jasd8as0da09sdas98d0a9s8d9as09s8das90sd",
    "path": "this_is_my_test_image.jpg"
}
上面的

None对后端有用。我需要传递二进制或 base64。 这是我的 jsx,其中 dropzone 被称为 redux-form 组件:

<form ....>
      <div className="form__form-group">
          <div className="form__form-group-field">
            <Field
              name='image'
              component={renderDropZoneField}
            />
          </div>
        </div>
</form>

renderDropZoneField 包括以下内容:

const DropZoneField = ({
  value, customHeight, name, onChange,
}) => {
  const files = value;
 

  const onDrop = (file) => {
    onChange(file.map(fl => Object.assign(fl, {
      preview: URL.createObjectURL(fl),
    })));
  };

  const removeFile = (index, e) => {
    e.preventDefault();
    onChange(value.filter((val, i) => i !== index));
  };

  return (
    <div className={`dropzone dropzone--single${customHeight ? ' dropzone--custom-height' : ''}`}>
      <Dropzone
        accept="image/jpeg, image/png"
        name={name}
        multiple={false}
        onDrop={(fileToUpload) => {
          onDrop(fileToUpload);
        }}
      >
        {({ getRootProps, getInputProps }) => (
          <div {...getRootProps()} className="dropzone__input">
            {(!files || files.length === 0)
            && (
              <div className="dropzone__drop-here">
                <span className="lnr lnr-upload" /> Drop file or click here to upload
              </div>
            )}
            <input {...getInputProps()} />
          </div>
        )}
      </Dropzone>
      {files && Array.isArray(files) && files.length > 0
      && (
          <aside className="dropzone__img">
            {
              !show && <img src={files[0].preview} alt="drop-img" />
            }
            {
              show && <AlertMessage />
            }
            
            <p className="dropzone__img-name">{files[0].name}</p>
            <button className="dropzone__img-delete" type="button" onClick={e => removeFile(0, e)}>
              Remove
            </button>
          </aside>
        )
      }
    </div>
  );
};

const renderDropZoneField = ({ input, customHeight }) => (
  <DropZoneField
    {...input}
    customHeight={customHeight}
  />
);

export default renderDropZoneField;

我在 github:https://github.com/react-dropzone/react-dropzone/issues/146 上找到了这条评论,其中来自 react-dropzone 插件的人建议使用以下代码:

onDropHandler(files) {      
      var file = files[0]
      const reader = new FileReader();
      reader.onload = (event) => {
        console.log(event.target.result);
      };
      reader.readAsDataURL(file);
}

我对下降常量进行了以下更改:

const onDrop = (file) => {
    onChange(file.map(fl => Object.assign(fl, {
      preview: URL.createObjectURL(fl),
      base64: convertToBase64(fl). <---- this is the change
    })));

其中 convertToBase64 函数将图像转换为 base64。这是我的功能:

export const convertToBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = () => {
      resolve(fileReader.result);
    };
    fileReader.onerror = (error) => {
      reject(error);
    };
  });
};

在通过 axsio API 发送图像之前,这是 console.log 中的样子:

如您所见,Promise 已被解析,结果中有一个 base64 代码,但是当我通过 API 发送它时,有效负载如下所示:

{
    "image": [
        {
            "path": "unnamed.jpeg",
            "preview": "blob:http://localhost:3000/e270e022-44e2-4d6b-b34a-dff1fce65033",
            "base64": {}
        }
    ]
}

Base64 作为空对象发送。 非常感谢任何帮助。

我找到了解决方案。这很容易,但当时没有考虑。

您需要将结果存储在某个地方(在我的例子中是本地存储),然后从 DropZone 组件中获取它。 这里的变化:

export const convertToBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = () => {
      resolve(fileReader.result);
      localStorage.setItem('base64', fileReader.result);
    };
    fileReader.onerror = (error) => {
      reject(error);
    };
  });
};

那么您需要进行以下更改:

const onDrop = (file) => {
    convertToBase64(file)

    onChange(file.map(fl => Object.assign(fl, {
      preview: URL.createObjectURL(fl),
      base64: localStorage.getItem('base64');
    })));