需求
想使用antdesign的Form实现类似youtube的评论表单。
初始包括
- 头像
- 输入框
聚焦(点击输入框或tab)输入框的时候
输入框下面显示
取消按钮
和评论按钮
- 两者靠右对齐
- 当输入框中的内容为空的时候,
评论按钮
为disabled
- 取消输入框聚焦(鼠标点击其他位置或tab到其他可聚焦元素)的时候,保持不变。
- 按取消键,输入框底部的两个按钮消失,当前输入框中的内容清空。
尝试
import { Form, Avatar, Flex, Input, Button, Space } from "antd";
import React from "react";
function CommentForm() {
const [show, setShow] = React.useState(false);
const [form] = Form.useForm();
const comment = Form.useWatch("comment", form);
function handleReset() {
console.log("handle reset");
form.resetFields();
setShow(false);
}
console.log("comment ", comment);
return (
<Flex gap="small" align="start">
<Avatar>P</Avatar>
<Form
onFinish={() => console.log("Finished")}
className="grow"
form={form}
>
<Form.Item name="comment">
<Input
placeholder="添加一条评论"
onFocus={() => !show && setShow(true)}
/>
</Form.Item>
{show && (
<Flex justify="end">
<Form.Item wrapperCol={{ span: 4, offset: 0 }}>
<Space>
<Button htmlType="reset" onClick={handleReset}>
取消
</Button>
<Button htmlType="submit" disabled={!comment}>
评论
</Button>
</Space>
</Form.Item>
</Flex>
)}
</Form>
</Flex>
);
}
export default CommentForm;
问题:
如何在聚焦时候的时候让两个按钮出现同时在取消聚焦的时候保持不变呢?
onFocus
+show state
- 还有其他更好的方案吗?
如何使两个按钮向右对齐?
- 方案一: 在
Form.Item
的外面套一层Flex
, 设置justify="end"
。 - 方案二:
Form
其实使用了栅格来对Form.Item
来进行布局, 设置wrapperCol={{span: ?, offset: ?}}
,offset
只能相对于左侧,设置多少得用眼来估计,并不准确。 - 还有其他更好的方案吗?
- 方案一: 在
如何在点击取消按钮的时候使按钮消失,并清空输入框?
onClick
中setShow(false)
使按钮消失如何清空输入框?
使用
Form.useForm()
产生一个formInstance
传入Form
,然后在onClick
中调用resetFields
,但是当传入Form
的时候报错了Cannot set properties of undefined (setting 'name')
。- 后来发现应该是
const [form] = Form.useForm()
而不是const form = Form.useForm()
。
- 后来发现应该是
如何知道当前的输入框是否为空?
方案一:设置一个新的状态,将
value
,onChange
绑定到Input
上?读文档发现表单控件会自动生成value
和onChange
来控制数据,不能再使用value
来设置数据,不应该使用setState
。- 行不通
- 方案二:借助
Form.useWatch("comment", form)
就可以获取当前comment
的值了。
还有其他更优雅的实现方案吗?
附文档中相关说明:
被设置了 name 属性的 Form.Item 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:
- 你不再需要也不应该用 onChange 来做数据收集同步(你可以使用 Form 的 onValuesChange),但还是可以继续监听 onChange 事件。
- 你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。
- 你不应该用 setState,可以使用 form.setFieldsValue 来动态改变表单值。