reactjs - 如何将图像预加载到 react-dropzone 中?
问题描述
在我的项目中,我使用 React + Redux 和 redux-forms 来处理表单。我已经能够将字段预加载到 redux 表单中(为了更新它们的值),但是我无法使用 react-dropzone 对图像字段执行相同的操作。这是我加载表单时出现在页面上的内容:
我希望也可以预先填充现有图像。数据被提供给这样的表格:
{
"name":"Salted Butter",
"cost":"4",
"quantifier":"grams",
"servings":"250",
"quantity":"250",
"img":"data:image/jpeg;base64,/9j/4AAQSkZJRgABA...."
}
这是我到目前为止所拥有的:
ImageInput.jsx(组件传递到 redux-form 字段)
import React from 'react';
import ImageInputPreview from "../../atoms/placeholders/ImageInputPreview";
import ImageInputPlaceholder from "../../atoms/placeholders/ImageInputPlaceholder";
import DropZone from 'react-dropzone';
const ImageInput = ({ handleOnDrop, input: { onChange }, imagefile, meta }) => (
<div>
<DropZone
accept="image/jpeg, image/png, image/gif, image/bmp"
onDrop={(file) => {
handleOnDrop(file, onChange);
}}
>
{({ getRootProps, getInputProps }) =>
imagefile && imagefile.length > 0 ? (
<ImageInputPreview imagefile={imagefile} />
) : (
<ImageInputPlaceholder
error={meta.error}
touched={meta.touched}
getInputProps={getInputProps}
getRootProps={getRootProps}
/>
)
}
</DropZone>
</div>
);
export default ImageInput;
IngredientForm.jsx(用于创建和编辑成分的表单)
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { reduxForm, Field } from 'redux-form';
import AbstractTextInput from '../../atoms/forms/AbstractTextInput';
import CurrencyInput from '../../atoms/forms/CurrencyInput';
import QuantityInput from '../../atoms/forms/QuantityInput';
import TitleInput from '../../atoms/forms/TitleInput';
import SubmitButton from '../../atoms/buttons/SubmitButton';
import { upsertIngredient, getIngredient } from '../../../actions/ingredient';
import { withRouter } from 'react-router';
import ImageInput from "../../molecules/forms/ImageInput";
class IngredientForm extends Component {
state= { imageFile: [] };
// Preloads react-redux form if provided on props.preload
componentDidMount = async () => {
if (this.props.preload) {
this.props.initialize(this.props.preload);
}
}
// ImageInput function for handling image upload
handleOnDrop = (newImageFile, onChange) => {
const imageFile = {
file: newImageFile[0],
name: newImageFile[0].name,
preview: URL.createObjectURL(newImageFile[0]),
size: newImageFile[0].size
};
console.log('upload:', imageFile);
this.setState({ imageFile: [imageFile] }, () => {
onChange(imageFile)
});
};
// Handle form submissions
onSubmit = async formValues => {
// Convert image to base64
const file = this.state.imageFile[0].file;
const reader = new FileReader();
let fileAsBase64 = '';
reader.onload = () => {
fileAsBase64 = reader.result;
}
reader.onabort = () => console.log("file reading was aborted");
reader.onerror = () => console.log("file reading has failed");
reader.readAsDataURL(file);
reader.onloadend = () => {
console.log(fileAsBase64);
// Call action for handling form input
return this.props.upsertIngredient({...formValues, img: fileAsBase64 });
}
}
/** Render the form. */
render() {
return (
<form onSubmit={this.props.handleSubmit((formValues) => this.onSubmit(formValues))}>
<Field
name="img"
component={ImageInput}
type="file"
imagefile={this.state.imageFile}
prefill={this.startWithImage}
handleOnDrop={this.handleOnDrop}
/>
<Field name='name' component={TitleInput} placeholder='Ingredient Name' />
<Field name='cost' component={CurrencyInput} placeholder='Cost' />
<Field name='quantity' component={QuantityInput} placeholder='Quantity' />
<Field name='quantifier' component={AbstractTextInput} placeholder='cups/slices/grams/etc.' />
<SubmitButton type='submit' >{this.props.preload ? 'Update' : 'Create'}</SubmitButton>
</form>
);
}
}
/** Validates form fields and passes errors to redux-form to process. */
const validate = (formValues) => {
const errors = {};
// Required fields
if (!formValues.name) { errors.name = 'You must enter an ingredient name'; }
if (!formValues.cost) { errors.cost = 'You must enter a cost'; }
if (!formValues.quantity) { errors.quantity = 'You must enter a quantity'; }
if (!formValues.quantifier) { errors.quantifier = 'You must enter a quantifier'; }
// Cost validation
if ( isNaN(formValues.cost) ) { errors.cost = 'Cost must be a number'; }
if ( formValues.cost < 0 ) { errors.cost = 'Cost must be at least 0'; }
// Quantity validation
if ( isNaN(formValues.quantity) ) { errors.quantity = 'Quantity must be a number'; }
if ( formValues.quantity <= 0 ) { errors.quantity = 'Quantity must be greater than 0'; }
return errors;
}
/** Removes values from form on successful submit. */
const onSubmitSuccess = (result, dispatch, props) => {
props.history.push(`/ingredients`);
}
/** Configure the redux-form and wrap the component. */
const formWrapped = reduxForm({
form: 'IngredientForm',
validate,
onSubmitSuccess
})(IngredientForm);
// Wrapping Order: withRouter > connect > formWrapped > component
export default withRouter(
connect(null, { upsertIngredient })(formWrapped)
);
IngredientEditPage.jsx(将值预加载到表单中的页面)
import React, { Component } from 'react';
import { connect } from 'react-redux';
import IngredientForm from '../../organisms/forms/IngredientForm';
import Container from '../../molecules/layout/Container';
import PageTitle from '../../atoms/text/PageTitle';
import { getIngredient } from '../../../actions/ingredient';
class IngredientEditPage extends Component {
componentDidMount = () => {
const { getIngredient } = this.props;
getIngredient(this.props.match.params.name);
}
render () {
return (
<Container paddingTop={50} paddingBottom={50} >
<PageTitle>Edit Ingredient</PageTitle>
{ this.props.formData
&& <IngredientForm preload={this.props.formData} /> }
</Container>
);
}
}
const mapStateToProps = ({ ingredients }, { match }) => {
const name = match.params.name;
return { formData: ingredients[name] };
}
export default connect(mapStateToProps, { getIngredient })(IngredientEditPage);
解决方案
推荐阅读
- java - Okhttp3:使用 HeaderInterceptor 需要帮助
- python - Python gTTS几个mp3文件问题
- java - 如何使recyclerview中的进度条不可见
- android - 如何连接一些 Firebase 数据库,其 google-services.json 未添加到我的应用中
- postgresql - 将数据库从 sqlite 转换为 postgres 的问题
- c# - 使用嵌套括号拆分字符串,但将它们保留在自己的组中
- c++ - 如何创建智能指针向量
- javascript - 根据其他对象值更改对象键
- flutter - 如何在颤动中通过滚动控制器中途调用函数
- html - 切换时图标不旋转