我正在尝试使用redux-saga和formik做一个简单的文件上传,以处理我的表单。
服务器不断返回400 error
(无效输入),我的服务器需要具有属性formData
的{{1}}对象。
这是我使用Formik的表格:
file
我正在使用Ant Design中的自定义上载组件,当新文件已被上载并将其正确添加到 <Formik
initialValues={{ file: null }}
validationSchema={CreateWorkspaceSchema}
onSubmit={(values: FormikValues, { resetForm }: FormikActions<FormikValues>) => {
resetForm({})
onSubmit(values)
}}
>
{({
values,
errors,
touched,
handleChange,
handleSubmit,
setFieldValue
}) =>
<Modal
title="Create a workspace"
visible={showModal}
onOk={handleSubmit}
okButtonProps={{ htmlType: "submit" }}
onCancel={onShowModal}
okText='Create'
>
<Spin spinning={status === ProgressStatus.InProgress}>
{message ? <Alert type="error" closable message={message} showIcon style={{ marginBottom: "10px" }} /> : null}
<Form onSubmit={handleSubmit}>
<Upload beforeUpload={() => false} multiple={false} name="file" listType="picture" onChange={(event) => {
setFieldValue("file", event.fileList[0]);
}}>
<Button>
<Icon type="upload" /> Upload image
</Button>
</Upload>
</Form>
</Spin>
</Modal>
}
</Formik>
onChange
将启动
我的formikValues
负责启动我的onSubmit
操作:
redux-saga
我的传奇:
onCreateWorkspace = (values: FormikValues) => {
const { user, createWorkspace } = this.props;
createWorkspace(Object.assign(
values,
{
owner: `api/users/${user.id}`
}
) as CreateWorkspaceValues)
}
我尝试添加以下标头:
const formData = new FormData();
formData.append('file', action.payload.file)
const fileResponse = yield call(
fetch,
`${api.url}/api/media_objects`,
{
method: 'POST',
body: formData
}
);
return console.log(fileResponse);
但是错误仍然保持不变。
我尝试在Postman中进行相同的操作,以查看我的后端服务器是否出了点问题,但是在postman中上传的文件可以正常工作。我在邮递员中上传的内容如下:
我在这里想念什么?
答案 0 :(得分:0)
前段时间我也遇到过同样的问题,而且似乎解决方案“简单”但难以理解,因为道具的流动不是很明显(至少对我而言)。我将尽可能简单地描述如何设法通过redux-saga
上传文件的概述:
首先,为了将我们的Formik
组件与redux
连接起来,我们需要用HOC包装它。可以使用withFormik()
API来完成此操作,
import { connect } from 'react-redux';
import { withFormik } from 'formik';
import Demo from './Demo'; // <--- the form component to be upgraded using this HOC
import * as types from './types';
const Form = withFormik({
handleSubmit: (values, { props }) => {
props.uploadFile(values); // <<--- Some action passed down from redux connect
}
})(Demo);
const mapStateToProps = state => ({
uploading: state.uploading
});
const mapDispatchToProps = dispatch => ({
uploadFile: (
values // <<-- Here's where the action is passed down
) =>
dispatch({
type: types.UPLOAD_FILE_REQUEST,
payload: values
})
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Form);
第二,既然我们已经升级了Formik
组件,则可以进行dispatch
动作并在其中使用我们的商店。
最后,为了上传文件,我们可以使用redux-saga
如下:
import { put, takeLatest } from 'redux-saga/effects';
import * as types from './types';
import reqwest from 'reqwest';
import { message } from 'antd';
function* uploadFileSaga({ formData }) {
try {
// You can use any AJAX library you like
const request = yield reqwest({
url: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
method: 'post',
processData: false,
data: formData,
success: () => {
message.success('upload successfully.');
},
error: () => {
message.error('upload failed.');
}
});
if (request.status === 'done') {
yield put({ type: types.UPLOAD_FILE_SUCCESS });
}
} catch (e) {
console.log(e);
}
}
export default function* rootSaga() {
yield takeLatest(types.UPLOAD_FILE_REQUEST, uploadFileSaga);
}
此传奇使用reqwest
处理AJAX调用(与Ant-Design所使用的相同)。尽管您可以选择要使用的任何库。
您可以进入此sandbox并观看完整的演示以及它如何与Ant-Design一起工作。