我目前正在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
错误。
我该怎么做?