问题描述:我一个页面有多个Modal嵌套Form的组件,现在需要点击各个Modal的OK键取出对应Form里面的值,但是,当仅存在一个Modal时没问题,多个时就报错TypeError: form.validateFilds is not a function,应该是settingFormRef = (form) => {
this.form = form;
};
const form = this.form;
上面的form没取到值。页面用了多个Form.create()。
对react、ref神马一知半解的菜鸟求解。。。。。。
其中某一个子组件:
class ModifyPhone1 extends PureComponent{
constructor(props) {
super(props);
this.state = {
isSend:false,
};
}
/*发验证码*/
sendCodeOldPhone=()=>{
const {user:{currentUser:{phone}}} = this.props;
const {dispatch} = this.props;
const payload = {phone};
dispatch({
type:'settings/sendVerificationCode',
payload,
callback:()=>{
this.setState({
isSend:true,
})
}
});
};
onhandlePhone=()=>{
this.sendCodeOldPhone();
};
render(){
const {getFieldDecorator} = this.props.form;
const {user:{currentUser:{phone}}} = this.props;
return(
<Modal
title={this.props.title}
visible={this.props.visible}
confirmLoading={this.props.confirmLoading}
onOk={this.props.handleOK}
okText='确定'
cancelText='取消'
onCancel={this.props.onCancel}
>
<Form layout='horizontal' hideRequiredMark='true'>
<FormItem>
<Row>
<Col span={6}><img src={light} className={styles.img}/><span className={styles.numLocation}>1</span><span className={styles.title1}>验证身份</span></Col>
<Col span={3}><Icon type="caret-right" style={{color:'#CFD1D2',fontSize:16}} /></Col>
<Col span={6}><img src={gray} className={styles.img}/><span className={styles.numLocation}>2</span><span className={styles.title2}>修改手机</span></Col>
<Col span={3}><Icon type="caret-right" style={{color:'#CFD1D2',fontSize:16}} /></Col>
<Col span={6}><img src={gray} className={styles.img}/><span className={styles.numLocation}>3</span><span className={styles.title2}>完成</span></Col>
</Row>
</FormItem>
<FormItem>
<Row>
<span>当前手机号:{phone}</span><span>(如果手机号不能用,请联系客服)</span>
</Row>
</FormItem>
<FormItem>
<Row gutter={8}>
<Col span={18}>
{getFieldDecorator('verificationCode1',{
rules:[{required:true,message:'请输入短信验证码'}],
})(
<Input placeholder='请输入短信验证码'/>
)}
</Col>
<Col span={6}>
{/*<Button type='default'>获取验证码</Button>*/}
<SendVerifyCode
isSend={this.state.isSend}
onhandlePhone={this.onhandlePhone}
// onSuccessSend={this.onSuccessSend}
/>
</Col>
</Row>
</FormItem>
</Form>
</Modal>
)
}
};
ModifyPhone1.propTypes = {
title: PropTypes.string.isRequired,
visible: PropTypes.bool,
initValues: PropTypes.object,
onCancel: PropTypes.func,
handleOK: PropTypes.func,
confirmLoading: PropTypes.bool
};
const WrappedModifyPhone1 = Form.create()(ModifyPhone1);
父组件:
class Security extends PureComponent{
componentDidMount(){
const {dispatch}=this.props;
}
/*弹出修改手机-验证旧手机Modal*/
showModalModifyPhone1=()=>{
this.setState({
modifyPwd:false,
modifyPhone1:true,
modifyPhone2:false,
modifyPhone3:false,
});
};
/*Modal-取消*/
handleCancel=()=>{
this.setState({
modifyPwd:false,
modifyPhone1:false,
modifyPhone2:false,
modifyPhone3:false,
})
};
/*关闭Modal*/
cancelModal = () => {
this.setState({
modifyPwd: false,
modifyPhone1:false,
modifyPhone2:false,
modifyPhone3:false,
});
};
settingFormRef = (form) => {
this.form = form;
};
/*
验证旧手机
*/
**handleModifyPhone1 = () => {
const form = this.form;
console.log('验证旧手机');
console.log(form);
form.validateFilds((err,values)=>{
if(err){
return;
}
//处理表单values
if(values.verificationCode1&&values.verificationCode1.length>0){
const {dispatch} = this.props;
const payload = produce(values,draft=>{
let code = draft.verificationCode1;
draft.code = code;
delete draft.verificationCode1;
});
dispatch({
type:'settings/modifyPhoneOne',
payload,
callback:()=>{
this.setState({
modifyPwd: false,
modifyPhone1:false,
modifyPhone2:true,
modifyPhone3:false,
});
}
});
}
});
};**
constructor(props) {
super(props);
this.state = {
// visible: false,
modifyPwd:false,
modifyPhone1:false,
modifyPhone2:false,
modifyPhone3:false,
initValues: null, // 初始值
modalTitlePwd: '修改密码',
modalTitlePhone:'修改手机',
};
}
render() {
return (
......
{/*修改密码弹框*/}
<WrappedModifyPwdForm
// ref={this.settingFormRef}
title={this.state.modalTitlePwd}
visible={this.state.modifyPwd}
initValues={this.state.initValues}
onCancel={this.cancelModal}
handleOK={this.handleModifyPwd}
destroyOnClose={true}
/>
{/*修改手机-验证旧手机*/}
<WrappedModifyPhone1
ref={this.settingFormRef}
title={this.state.modalTitlePhone}
visible={this.state.modifyPhone1}
initValues={this.state.initValues}
onCancel={this.cancelModal}
handleOK={this.handleModifyPhone1}
destroyOnClose={true}
/>
{/*修改手机-验证新手机*/}
<WrappedModifyPhone2
// ref={this.settingFormRef}
title={this.state.modalTitlePhone}
visible={this.state.modifyPhone2}
initValues={this.state.initValues}
onCancel={this.cancelModal}
handleOK={this.handleModifyPhone2}
destroyOnClose={true}
/>
{/*修改手机-修改成功*/}
<ModifyStatus
// ref={this.settingFormRef}
title={this.state.modalTitlePhone}
visible={this.state.modifyPhone3}
initValues={this.state.initValues}
onCancel={this.cancelModal}
handleOK={this.handleModifyPhone3}
destroyOnClose={true}
/>
</Fragment>
)
}
}
export default Security;
有人问过类似的问题, 已经有解答的了
https://segmentfault.com/q/1010000011100793
可以参考一下, 希望能帮助你
https://github.com/react-component/form#formoptionwithref-boolean
这个是官方的文档里面也有说明的
另外友情提醒一下, 代码最好format一下再发出来, 不然看着太难受。
代码不看了,但是form.validateFild明显field这个单词写错了是form.validateField
真乱啊。。。
首先 handleModifyPhone1 这个方法内 form.validateFilds 应该是 form.validateFields,
然后 如果是这个5组件引用指向的是一个组件的话不用重新定义这么多次,引用一次写多个就可以了,然后在handleOK内写个type或者在提交的dispatch这入手利用type属性写个正则就可以了
另外 ref={this.settingFormRef}这确实有问题,5个属性都是赋值给了 this.form ,但是你在这写入了5个组件这是this.form就会冲突目前照着你的思路来看 解决这个问题需要写5个this.form1,this.form2,this.form3...然后在handleOK分别使用
最后还还有一个方法,把 form.validateFields放在子组件内
form.validateFields((err,values)=>{
if(err){
abc(values)
}
然后向外部暴露abc这个方法在父组件内在abc中使用dispatch提交数据就可以