持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
前言
最近在公司学习做项目需求的时候,会碰到各种问题,这篇文章主要讲述一下我遇到的问题踩过的坑以及开发相关功能如何达到效率并且符合规范的做法。希望这篇文章能够帮助到正在写各种页面各种功能的同学~~~话不多说,我们现在就直接开始吧。
公司的项目利用的组件库是Acro Design,当我们需要开发某一个功能比如在多个输入框中添加校验功能以及需要获取每一个输入框的输入值的时候,一般我们会想到利用useRef来获取组件实例,这种多组件在一起的时候虽然利用useRef可以得到各种实例的值,但是难免有些影响我们的开发效率,今天让我们来认识一下Acro Design中的From组件。
具体内容
关于为什么会用Acro来进行开发,理由是Acro的文档写的很简便也很详细,比较适合开发,当然利用其它的组件库都是可以的。我们利用Form来包裹这些我们需要的组件,随后可以在Form.Item传入field属性,即可使控件变为受控组件,表单项的值都将会被 Form 收集。
受控组件就相当于Vue中的双向绑定,它依赖于状态,而非受控组件主要就是在虚拟DOM中使用ref获取实例的值,在我们让这些组件变成受控组件后,Acro Design会大大地节省了我们的开发时间,因为受控模式下Form.Item会接管控件,自动给表单控件添加相应的 value(或 triggerPropName 指定的其他属性)和onChange(或 trigger 指定的其他属性),所有的数据收集都由 Form 内部完成。这样我们就可以直接在Form的标签上添加回调函数的API即可获取所有的组件的值,是不是特别方便?接下来就举个例子来说明一下实际操作。
比如下面的代码中,我想在父组件中让所有的子组件全部变成受控组件就只需要指定field属性即可
<Form>
<Row key={index}>
{group.map(item => {
const { id: layoutId, grid } = item;
const {
component: Component,
componentProps,
label,
fieldDecoratorProps,
id,
formItemProps,
} = formItems[layoutId]
return (
<Col key={layoutId} {...(grid || {})}>
<Form.Item
{...(formItemProps || {})}
label={label}
key={id}
field={id}
{...fieldDecoratorProps}
className={`ant-form-item-${index}`}
>
<Component {...componentProps} />
</Form.Item>
</Col>
);
})}
</Row>
</Form>
这段代码的所有组件配置全部写在了formItems中方便统一管理,我遇到的第一个坑就是在这里产生,我们要知道Form会自动帮助我们传value和onChange几个属性,但是在TS中,我们如果仅仅在子组件内部传入之前配置好的传值后,如果我们要使用value和onChange,ts就会默认我们没有传这两个属性,因为这两个属性的传值是Acro帮我们传入的,所以我们必须在子组件传入值的时候对传入的值进行类型断言,不然就会一直报错。
function bookInfo({ value, onChange, book_id }) {
const { book_name: bookName, status, author, book_id: bookId } = value || {};
return (
<div className="book-info">
XXXXXXXX
</div>
);
}
在进行类型断言后我们才能够正确的使用Form给我们传入的这两个属性,最后只需要利用这两个属性进行相关操作即可。比如我们传的value值定义为在输入框搜索过后调接口产生的结果,随后利用回调函数传值。
const handleSearch = useCallback(
async value => {
try {
//进行相关接口的实现
const { code, data } = res;
if (code === 0 && data.genre !== BookGenre.COMIC) {
typeof onSearch === 'function' && onSearch(data);
} else {
onSearch(null);
}
} catch (e) {
onSearch(null);
}
},
[inputText],
);
useEffect(() => {
if (inputText) {
handleSearch(inputText);
}
}, []);
总结
文章的最后,希望这篇文章能够带给一些帮助给你,当然有错误的话也希望能够及时指正!