【发布时间】:2019-05-24 06:13:09
【问题描述】:
在这个项目中,我有一个带有input type='file' 的 Redux 表单,用于将图像上传到 Cloudinary,同时将其他数据上传到 MongoLab。该表单与项目 (Book) 创建组件 (booklist\client\src\components\AddBook.js) 和用于编辑 Book (booklist\client\src\components\Book.js) 的组件一起重用。
AddBookForm 表单。 book 属性存在时来自父 Book 组件。其他的Fields 被省略了。
class AddBookForm extends Component {
componentDidMount() {
this.handleInitialize();
}
handleInitialize() {
let names = '';
if (this.props.book) {
const authors = this.props.book.authors && this.props.book.authors.map(ath => {
let str = `${ath.firstname} ${ath.lastname}, `;
names = names + str;
});
names = names.slice(0, -2);
}
const initData = {
'title': this.props.book && this.props.book.title || '',
'pages': this.props.book && this.props.book.pages || 0,
'publisher': this.props.book && this.props.book.publisher || '',
'publishedAt': this.props.book && moment(this.props.book.publishedAt).format('MM.DD.YYYY') || '',
'releasedAt': this.props.book && moment(this.props.book.releasedAt).format('MM.DD.YYYY') || '',
'isbn13': this.props.book && this.props.book.isbn13 || '',
'cover': this.props.book && this.props.book.cover || '',
'authors': names,
book_id: this.props.book && this.props.book._id,
cloudinarySecureUrl: this.props.book && this.props.book.cloudinarySecureUrl
};
this.props.initialize(initData);
}
render() {
const { onSubmit, handleSubmit, pristine, reset, submitting } = this.props;
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Field
name='cover'
type='file'
component={fileField}
label='Cover'
comment='Please provide a cover. Optional'
/>
<button
disabled={submitting}
className='add-form-action'
>
Add Book
</button>
<button type='button' disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</form>
)
}
export default AddBookForm = reduxForm({
form: 'AddBookForm'
})(AddBookForm);
处理表单提交的Book组件方法
onSubmit(formData) {
const authors = formData.authors;
const authorsToArray = [];
const authorsArray = authors.split(',');
for (let ath of authorsArray) {
const firstname = ath.trim().split(' ')[0];
const lastname = ath.trim().split(' ')[1] || '';
authorsToArray.push({
firstname,
lastname
});
}
formData.authors = authorsToArray;
this.props.addBook(formData, this.props.history);
}
这是处理Book 表单数据上传的addBook() 操作。
export const addBook = (bookData, history) => (dispatch) => {
const cloudinaryUrl = 'https://api.cloudinary.com/v1_1/*******/upload';
const cloudinaryUploadPreset = '*******';
const formData = new FormData();
formData.append('file', bookData.cover[0]);
formData.append('upload_preset', cloudinaryUploadPreset);
axios({
url: cloudinaryUrl,
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formData
})
.then(res => {
bookData.cloudinarySecureUrl = res.data.secure_url;
axios.post('/api/books', bookData)
.then(res => {
history.push('/')
})
.catch(err => dispatch({
type: GET_ERRORS,
payload: err.response.data
}));
})
.catch(error => console.log('Cloudinary image upload error:', error.message));
};
我默认bookData.cover[0] 是什么,以便我可以提交没有Field name='cover' 图像的表单?有/我应该采取其他方式吗?完整的 repo 在https://github.com/ElAnonimo/booklist
更新
在编辑Book 时不上传图片的addBook() 操作的catch 子句中添加了这个,我得到了正确的图书列表,即使图片从上传图片时起仍然存在。
.catch(error => {
history.push('/');
});
【问题讨论】:
标签: reactjs redux-form cloudinary