将图像添加到Redux Store

时间:2019-03-26 16:58:40

标签: reactjs redux react-dropzone

我目前正在React中创建一个表单。理想的行为是将提交多个文本字段和一个或多个图像,其中文本字段POST到API终端节点,并且图像进入AWS S3存储桶。我在这里宽松地使用“表单”一词,因为这是两个不同的操作,只有文本字段才是HTML表单的一部分,但是图像提交只会由相同的按钮触发。

所有这些都适用于任何文本字段数据,并单独测试S3提交。但是,我在正确处理客户端上的图像时遇到困难。

对于表单的“添加图像”部分,我在子组件中使用react-dropzone。这是该子组件:

const Dropzone = (props) => {
  const { classes, receiveLogin, switchScreen, addFormImages, loginReducer, screenReducer, imageFormReducer } = props;

  const [files, setFiles] = useState([]);
  const {getRootProps, getInputProps} = useDropzone({
    accept: 'image/*',
    onDrop: acceptedFiles => {
      const _fileProperties = [
        'lastModified',
        'lastModifiedDate',
        'name',
        'path',
        'preview',
        'size',
        'type',
        'webkitRelativePath'
      ];

      let newState = files.concat(acceptedFiles.map(file => Object.assign(file, {
        preview: URL.createObjectURL(file)
      })));
      setFiles(newState);
      console.log('newState in onDrop: ',newState);
      // console.log('Array.isArray(newState) in onDrop: ',Array.isArray(newState));

      const reader = new FileReader();

      let reduxArr = [];
      for (let i in newState) {

        // PUSH SOMETHING HERE
        reduxArr.push(SOMETHING);
      }
      addFormImages(reduxArr);
    }
  });

  const Delete = (file) => {
    const updatedFiles = files.filter(f => f.preview !== file.preview);
    setFiles(updatedFiles);
    addFormImages(updatedFiles);
  }

  const thumbs = files.map(file => (
    <div className={classes.thumb} key={file.name}>
      <DeleteIcon className={classes.delete} onClick={() => Delete(file)}/>
      <div className={classes.thumbInner}>
        <img
          src={file.preview}
          className={classes.img}
        />
      </div>
    </div>
  ));

  useEffect(() => () => {
    // Make sure to revoke the data uris to avoid memory leaks
    files.forEach(file => URL.revokeObjectURL(file.preview));
  }, [files]);

  return (
    <section>
      <Grid container className={classes.fileUploadGrid}> 
        <Grid item xs>
          <Grid 
            container
            direction="column"
            alignItems="center"
          >
            <div {...getRootProps()}>
              <input {...getInputProps()} />
              <Button variant="raised" component="span" className={classes.uploadButton}>
                Add Pictures
                <AddPhotoAlternateIcon />
              </Button>
            </div>
          </Grid>
        </Grid>
      </Grid>
      <Grid container className={classes.fileUploadGrid}> 
        <Grid item xs>
          <Grid 
            container
            direction="column"
            alignItems="center"
          >
            <aside className={classes.thumbsContainer}>
              {thumbs}
            </aside>
          </Grid>
        </Grid>
      </Grid>
    </section>
  );
}

addFormImages是一种Redux动作,它将接受一系列图像。

如果在for循环中将newState[i]推到reduxArr,则会收到错误Objects are not valid as a React child (found: [object File]). If you meant to render a collection of children, use an array instead。我尝试使用this question的答案,建议以两种不同的方式使用FileReader,但仍然会出错。

我尝试直接使用父组件中子组件中的代码来尝试使用Redux存储,但由于react-dropzone在内部使用了钩子,因此出现了Hooks can only be called inside the body of a function component错误。

我该怎么做?

0 个答案:

没有答案