提示:以上遇到的问题基于antd 3x版本
Form表单问题
1、修改弹窗回显数据时读取到的ref为空
场景说明:封装了一个修改数据的弹窗组件,需要数据回显,大致代码如下
/* index.js*/
// 显示修改项目 弹窗的事件
showModifyModal = ()=>{
const data = this.state.selectedData
this.formRef.initForm(data)
this.setState({visible:true})
}
render(){
const {visible} = this.state
return( <ModifyModal
visible={visible}
onCancel={()=>this.setState({visible:false})}
wrappedComponentRef={(form) => this.formRef = form}
/>)
}
/*ModifyModal.js*/
initForm = (data)=>{
console.log("data",data)
this.props.form.setFieldsValue(data)
}
render(){
return(
<Modal>
<Form>
<Form/>
<Modal/>
)
}
遇到的问题:调取this.props.form为空,所以在 this.props.form.setFieldsValue(data)这一步报错
解决方法
// 修改前:
render(){
return(
<Modal>
<Form>
<Form/>
<Modal/>
)
}
// 修改后:
render(){
return(
<Form>
<Modal>
<Modal/>
<Form/>
)
}
/*
为什么会这样的原因:我的猜测是模态框这个组件的挂载存在延时或者异步?所以包裹在模态框里面的Form组件在父组件挂载上去之后还是未能渲染到页面上,所以this.props.form读取到的值是null.
*/
总结:其实这样的写编辑弹窗数据回显的方法真的不好,因为data(需要回显的数据)本来就已经存储在state里面了,直接把这个数据传入子组件就可以了
至于我当时为什么用这种写法呢?可能是因为类组件真的不好监听数值的变化,不像函数组件一个useEffect就能监听指定某个值的变化,所以想在父组件中的显示函数中调用数据回显的方法。
但其实也可以在子组件componentDidMount的方法中调用initForm ,但是在父组件中需要在visible===false的时候显示null,如下:
render(){
const {visible} = this.state
return( {
visible?
<ModifyModal
visible={visible}
onCancel={()=>this.setState({visible:false})}
wrappedComponentRef={(form) => this.formRef = form}
/>:null
}
)
}
上面的方法只是稍微简化了一下代码,还是会有this.props.form读取到的值是null的问题出现的,还是需要将Form组件放在最外层包裹Modal组件
其实我感觉最好的方法还是使用函数组件,然后在useEffect监听data的变化,然后去执行initForm方法,用类组件应该不会出现props.form读取到的值是null的问题(所以我现在的开发原则都是能用函数组件的就坚决不用类组件,当然函数组件和类组件各有优势。类组件功能最为完备和强大,而函数代码简洁监听数据变化方便)
2、自定义表单检验无法提交的问题
// 校验批次号格式是否有数字字母和下划线之外的字符组成
const isValid = (rules,str,setErrorMsg)=>
{
if(!str) setErrorMsg("请输入项目编号")
const isTrue = /^[\w,-]+$/.test(str);
if(!isTrue){
setErrorMsg("只能输入'字母' '数字' '-' 或 '_' ")
}
setErrorMsg()//这个回调函数必须被执行 不然表单就无法提交
}
<Form.Item
label="项目编号"
name="lotProjectNumber"
rules={[
{
required: true,
validator:isValid,
}]}
>
<Input placeholder="批次号格式:由'数字' '字母' '-' 或 '_'组成"
onBlur={carryData} />
</Form.Item>
5703

被折叠的 条评论
为什么被折叠?



