专业编程基础技术教程

网站首页 > 基础教程 正文

React 基础:受控和非受控组件的总结(表单)

ccvgpt 2024-11-24 12:29:35 基础教程 1 ℃


前言

这系列是 React 基础教程(参考 React 官网),记录了自己入门学习 React 的笔记。不太适合有 React 丰富经验的同学,但希望看到此文的你,多少都有些收获。

React 基础:受控和非受控组件的总结(表单)

文章代码均可在我的码云中找到:https://gitee.com/eminoda/react-learn/branches

为了更好的阅读体验,可在底下的“了解更多”查看原文(我的语雀知识库)。

受控组件

表单元素(input、textarea、select 等)涉及输入/显示数据,一般用 state 来定义,并通过 setState 来更新。

就这样在 React 保证了一定的更新机制,这种控制表单元素的方式称为:"受控组件"。

说白了就是将表单数据交付给 React 的 state 来管理。

下面示例这些标签用法:



input

input 通过 onChange 触发事件,从 event 中拿到输入的值:

将该值设置到 state 对象中:

页面效果:



textarea

注意的是,为了和 input 和一样使用的方式,也在 textarea 中设置了 value 属性。



select

select 会略复杂,设计 options 选项的初始化定义,以及当前选项的定义。



通过遍历,定义 option 的 JSX 模板:


页面效果:



多 input 事件触发的封装

模拟一个稍稍复杂的表单,里面会有几个 input 元素。试想,如果每个 input 上定义一个事件函数,那将多冗余。


所以就有了如下使用方式,针对多 input 情况下的表单:


能看到表单的 JSX 模板上,定义了相同的事件函数 handleMultipleInput ,为了区分 input ,定义了不同的 name 属性:


最后通过统一的处理,来完成对这个表单数据对象的修改更新:


当然还有中需求,可能会对表单有些历史数据的回填,下面是示例:

比如,初始数据要对 sex 默认选中 female:

就要对模板这样修改:

事件中,有针对性的判断:


非受控组件

用法示例

如果了解 React 的 Ref 引用,那么就知道我们可以通过 Ref 的方式,直接获取 Dom 节点的引用,然后对表单的数据进行操作。


示例:

初始化 Ref :


将 Ref 交给 ref 属性,由 React 来对 Ref 进行 Dom 赋值:


测试:通过对应的事件方法,能实时获取到 input 输入的 value:



和"受控组件"不同,input 元素没有依靠 value={this.state.value} 这样的形式来显示数据。


初始化默认值

不像受控组件,可以在构造器中初始化 state 对象;对于非受控组件设置默认值需要其他方式:


通过 defaultValue 来指定首次渲染的数据。针对 checkbox、radio 是 defaultChecked 来指定。

受控和非受控的区别

受控组件

利用 state 实现数据的同步显示,这样有助于 form 表单验证的提示;

以及表单一些特殊情况的设置(disabled、级联显示等)

非受控组件

而非受控组件不擅长上述需求的定制,可以说偏业务简单的需求。因为表单数据可以直接从引用拿到,而且不带"副作用"(不像受控组件拿到子组件的实例全部引用)

当然非受控组件不是那么"无用",比如像 input 的 file 类型,更是它使用的独特场景。因为此 input 需要显示的值,我们控制不了。


总结

像受控组件,某种程度和 vue 或者 angular 的 model 类似,都有双向绑定的特点。

不管使用受控,还是非受控,React 能单独分离出这两个概念,我感觉很新奇。相信随着日益丰富的经验,这两者的使用会越来越准确。

最后,个人看官方文档还没有看到类似指令 directive 概念的出现,毕竟指令是专门处理 DOM 操作的地方。

相反,React 通过 Refs 来专项处理 DOM 操作,虽然"简单暴力",但总感觉是硬凑上去的概念,尤其是 Refs 的转发(个人观点)。

Tags:

最近发表
标签列表