最近的需求,两个下拉框是必填项,点击上传按钮,如果有下拉框没选要有提示,如图

如果直接使用antd的Upload组件,一点击文件选择的窗口就打开了,哪怕在Button里再加点击事件,也只是(几乎)同时处理两个方法,beforeUpload更是不行,文件都选择完了才执行。
在网上查找,终于看到这位vue选手的一个思路,两个同位置同样式的按钮按某个state切换:
AntD框架上传文件前校验信息:选择文件前进行内容校验并提示
改成react写法,把除了文件以外的payload获取放到beforeUpload里
- const [uploadData, setUpLoadData] = useState(null);
- const [selectMonth, setSelectMonth] = useState(false);
- const [selectaaa, setSelectaaa] = useState(false);
-
- const handleBeforeUpload = file => {
- if (!/.xls?$/.test(file.name) && !/.xlsx?$/.test(file.name)) {
- message.error('...');
- return false;
- }
- form.validateFields((err, fieldsValue) => {
- if (err) return;
- const month = moment(fieldsValue.month).format('YYYY-MM');
- setUpLoadData({...fieldsValue, month: month});
- });
- return true;
- };
组件里加onChange监听:
- <FormItem label="月份" {...formItemLayout}>
- {getFieldDecorator('month', {
- rules: [{ required: true, message: '请选择月份' }],
- })(
- <MonthPicker onChange={value => value ? setSelectMonth(true) : setSelectMonth(false)}/>
- )}
- FormItem>
最后上传按钮那边做两个按钮,用最上面定义的两个state来确定展示哪个按钮(validate里调用form.validateFields方法做必填提示):
- {selectDepartment && selectMonth ? (
- <Upload
- action={uploadUrl}
- data={uploadData}
- showUploadList={false}
- onChange={handleUpload}
- beforeUpload={handleBeforeUpload}
- withCredentials
- headers={}
- >
- <Button type="primary" style={}>
- <Icon type='cloud-upload' /> 上传数据
- Button>
- Upload>
- ) : (
- <Button type="primary" style={} onClick={()=>validate()}>
- <Icon type='cloud-upload' /> 上传数据
- Button>
- )
- }
就可以做到最开始提到的效果啦。
又看到一篇文章(https://zhuanlan.zhihu.com/p/590018131?utm_id=0),可以更优雅地监听form,不用再使用onChange方法和useState,改完发现自己项目antd版本太低了用不了,从antd@4.20.0 开始,antd Form 添加了一个新的 API ->Form.useWatch
- const [form] = Form.useForm();
- const aaa = Form.useWatch('aaa', form);
- const month = Form.useWatch('month', form);
在form item标签里加上name属性:
<FormItem label="月份" {...formItemLayout} name='month'>
效果应该是一样的。
另外发现使用dataform格式post方法上传文件,其他数据参数不需要用new FormData()再append进去了,直接传字典就行。