最近的需求,两个下拉框是必填项,点击上传按钮,如果有下拉框没选要有提示,如图
如果直接使用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 ? (<Uploadaction={uploadUrl}data={uploadData}showUploadList={false}onChange={handleUpload}beforeUpload={handleBeforeUpload}withCredentialsheaders={}><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进去了,直接传字典就行。