由于视频教程中用的antd版本还是低版本,当时还能用Form.create()方法,但是在本人学习的时候,该方法已经弃用,又觉得要解决问题,不能用降低版本的方式,既然弃用,肯定有新的解决方法,一味的跟视频模仿,学不了更多,首先看新版本的官方文档,
Form中的api,暂时没有找到能解决的,能力有限
<Modal title="修改分类"
visible={showStatus === 2}
onOk={this.updateCategory}
destroyOnClose={true}
onCancel={this.handleCancel}>
<UpdateForm categoryName={category.name}
setForm={(form) => { this.form = form }} />
</Modal>
找到外层Modal的api中有一个
使用这个可以清除
然后就是要在弹出的input框中显示预设修改值,而且不能只是单纯的用placeholder表示,因为placeholder只能展示,如果只是加几个字,还得挨着输入之前一样的数据,所以要把input的state里的value,在一弹出来就添加上,
查了半天,现在的antd4x不支持之前的方法了,可以用setFieldsValue的方法,但是这个方法要配合ref进行使用,用createRef(),在组件没有挂载前,ref并不会传出我们想要的setFieldsValue方法,只有当组件挂载后,ref才有意义,所以我最开始把setFieldsValue方法用在willMount上就报错,为null,要用在didMount中,但是总感觉加在这里,不是一弹出就显示,如果哪个环节加载慢了,就只能显示预设的placeholder了,所以这是双重保险让人眼反应不过来?虽然两者颜色不太一样。但是目前能力有限,暂时只能做到这个样子
componentDidMount() {
const { categoryName } = this.props
this.formRef.current.setFieldsValue({
input: categoryName//此处的键input是后面Item的name,Item是Form.Item,省略了前面的const Item = Form.Item
})
}
//为form创建一个ref
formRef = React.createRef()
render() {
const { categoryName } = this.props
return (
<Form
initialValues={categoryName}
ref={this.formRef}//给Form添加ref
onValuesChange={this.onFinish}
>
<Item name='input' >
<Input ref={input => this.props.setForm(input)}>
</Input>
</Item>
</Form>
)
}
总结,新版本的antd中class形式的Form组件可以用ref传递出Form创造的实例form,并用form的一系列方法,如何动态的使用呢,因为如果提前传出或者半路传出都无法得到想要的值,就可以在Form标签写上 onValueChange事件,进行绑定,在这个事件函数里面写就可以了(2021.4.19补充括号内的提醒,这种做法效率不高,因为每次input输入都会传出,但是只有最后一次完成的时候,传出的才能用,其他的都是冗余的,没有进行防抖,主要也是因为笔者当时还没接触到防抖节流,知道效率不高也没啥办法,当时能想出这种办法就挺高兴了哈哈),但是要在外部,将一个能传出ref的函数写到Form的props里面,如下
外部写:
<UpdateForm
categoryName={category.name}
setForm={(form) => { this.form = form }}
deliverForm={(form) => { this.deliForm = form }}
/>
内部写:
export default class UpdateForm extends Component {
//为form创建一个ref
formRef = React.createRef()
static propTypes = {
setForm: PropTypes.func.isRequired,
categoryName: PropTypes.string.isRequired,
deliverForm: PropTypes.func.isRequired,
}
deliverResult=()=>{
// 把form对象传出去,实时的,所以最后用的是完整的
this.props.deliverForm(this.formRef.current)
}
componentDidMount() {
const { categoryName } = this.props
// 设置的是name为input的组件的value
this.formRef.current.setFieldsValue({
input: categoryName
})
}
componentWillUnmount() {
console.log('我是update,我结束了');
}
render() {
return (
<Form ref={this.formRef} onValuesChange={this.deliverResult}>
<Item name='input'
rules={[
{
required: true,
message:'分类名称必须输入'
}
]}>
<Input
ref={input => this.props.setForm(input)}
>
</Input>
</Item>
</Form>
)
}
}
但是//会出现一种情况就是,如果不进行修改数据,就不会触发,那么就不会传出form对象,后续基于form的操作就无法实现
如何让其一上来就传递出form对象呢,可以在didmount里面在写一个,然后就可以保证运行了
componentDidMount() {
// 给分类下拉菜单添加初始值value,classer是select组件被包装成Item后的name
// select的option,value在这里是设置的c._id,所以会先渲染好每一个option
// 此处的预设初始值,是根据value来找到对应的option,该option是渲染好的,会显示c.name,下拉框会对应该项,并显示灰色
// 但是如果我设置此处的value为c.name,但是又是通过parentId找,那就找不到对应的option
// 那就会显示一个新的option,value和显示的都是parentId,并且在预先渲染好的下拉框中找不到,
const { parentId } = this.props
this.formRef.current.setFieldsValue({
classer: parentId
})
console.log(this.formRef.current);
// 一上来就得有一个form对象传出去,不然外面的操作无法进行
this.props.deliverForm(this.formRef.current)
//能工作,但是不能在didmount里面使用,因为这个是为了收集表单数据
// 但是,didmount里面只是刚打开这个弹窗,没有进行操作,所以无法得到想要的数据,
// 可以先预设值进去,然后在didmount里用,应该可以,注意先后顺序
// const aa = this.formRef.current.getFieldsValue()
// console.log('aa', aa);
// this.props.setForm(this.formRef)
}
可参考
https://blog.youkuaiyun.com/wqylry/article/details/110872012
https://blog.youkuaiyun.com/sky_blue6/article/details/108155215