浅谈React深度编程之受控组件与非受控组件
今天我们要的是React编程中的受控组件与非受控组件。长沙网络推广认为这是一个值得分享的话题,因此想和大家一同。如果你对React的表单处理有所好奇,那么这篇文章将为你揭示受控组件与非受控组件的神秘面纱。
在官网和国内网络上关于受控组件与非受控组件的资料虽然不多,但它们却是React处理表单的关键所在。有些人可能觉得这些概念可有可无,但对于后台系统和复杂表单来说,受控组件是不可或缺的。
在React中,表单元素具有特殊的意义,因为它们允许用户通过键盘输入和鼠标选择来改变界面显示。当界面发生变化时,一些数据也会随之改变。对于表单元素来说,最明显的数据变化是input的value、textarea的innerHTML、以及radio/checkbox的checked状态。除此之外,还有一些不太明显的数据变化,如option的selected和selectedIndex,这些变化是被动发生的。
当我们在JSX中使用input元素时,如果input的value是由组件的state.value决定的,那么当用户进行修改后,JSX需要重新渲染视图。这时就会面临一个问题:input的value应该采用用户的新值还是state的新值?React的解决方案是同时支持这两种方式,从而产生了受控组件与非受控组件的概念。
React认为value或checked不能单独存在,需要与一系列控制它们的属性或事件一起使用,如onInput、onChange、disabled、readOnly等。这些属性和事件共同构成了受控组件。如果用户没有提供这些额外的属性和事件,React会在内部添加一些默认的事件处理函数,以确保用户可以正常地进行输入或选择操作。在框架内部,有一个变量名为persistValue,它负责保持JSX上次赋予的值,只能由内部事件修改它。
受控组件的核心思想是通过事件来控制value或checked的状态。而persistValue变量在受控组件中始终能够被刷新更新。
深入理解 input 元素的 value 和 checked 属性,它们是 HTML 表单元素的核心特性。这些属性涉及到许多内部机制,如 oninput、onchange 事件以及输入法相关的事件。为了平稳地修改这些属性,我们需要深入理解并巧妙运用 JavaScript 的 Object.getOwnPropertyDescriptor 方法。
如果我们需要兼容 IE8 这样的旧版浏览器,那么这种方法可能并不适用。我选择了一种更为稳妥的方式,即只使用 Object.defineProperty 来修改 defaultValue 和 defaultChecked 属性。
为了确保我们的修改不会与用户的操作混淆,我为元素添加了一个 _uncontrolled 属性,以表示我们已经劫持了 defaultXXX。接下来,我们将通过描述对象(Object.defineProperty的第三个参数)的 set 方法来实现这一机制。在这个 set 方法中,我们添加一个开关 _observing。当框架内部更新视图时,此开关为 false,更新完成后置为 true。
具体实现如下:
接下来是 inputMonitor 的具体实现。我们定义了一个对象 inputMonitor,并通过正则表达式 rcheck 来判断当前元素是 checkbox 还是 radio。在 set 方法中,我们根据元素类型设置相应的控制属性(checked 或 value),并处理一些特殊情况,如 textarea 的内容设置。我们还通过 _observing 开关来判断当前的修改是框架操作还是用户操作。如果用户私下改变了 defaultValue,那么我们会清除 _setValue 标记。我们定义 get 方法来返回 _defaultValue,并设置描述对象的 configurable 属性为 true。
在 inputMonitor.observe 方法中,我们尝试使用 Object.defineProperty 来为 dom 定义新的属性。如果 dom 已经存在 _persistValue 属性,则设置 _setValue 为 true。
理解代码行为:
让我们看看这段代码的行为。在这段代码中,我们使用了React的ReactDOM来渲染textarea元素,并设置了它们的默认值。然后,我们预期这些元素的defaultValue、value、textContent和innerHTML等属性的值。值得注意的是,由于用户没有手动修改defaultValue,所以dom._setValue的值一直保持在false或undefined状态,而_persistValue则始终可以被修改。
接下来看另一个例子:
还有一些关于React中纯文本类元素(如text和textarea)的值的行为值得注意。这些值总是被转换为字符串。对于type为"number"的控件,值总是为数字类型,如果不填写或填写为空字符串,则默认转换为“0”。对于radio元素,同一父节点下的相同name的radio控件只能选择一个,这就是所谓的联动效果。而对于select元素,其value和defaultValue支持数组类型,不会对数组进行转换。如果用户对select元素下的option元素进行增加或删除操作,selected的值会跟着变动。select还有模糊匹配和精确匹配之分,这取决于具体的实现方式和用户需求。
React中的这些元素和属性都有其特定的行为方式和规则,了解这些规则可以帮助我们更好地理解和使用React。在React的世界里,选择框(select)的使用似乎成为了一种基础而重要的技能。对于精确的匹配与模糊的匹配,都有各自的应用场景和需求。让我们来深入理解一下这两者的差异。
让我们看看精确的匹配。假设我们有一段React代码,渲染了一个带有特定值的select元素。在此代码中,我们通过React的渲染函数ReactDOM.render来呈现一个带有选项的select元素,并且给这个select元素设置了一个value属性值为222。在select元素内部,我们定义了四个option元素,每个option元素都有一个value属性。当我们想要选中第三个option元素时,我们可以使用断言语句来验证是否成功选中。这里的选中逻辑是严格按照value属性的值来匹配的。这就是精确的匹配方式。
然后,让我们转向模糊匹配。同样是这段代码,如果我们想要选中第二个option元素(注意这里的“第二个”是基于用户在页面上看到的顺序来定义的,而非基于value属性的值),我们就会遇到一些问题。因为在HTML中,option元素的显示顺序并不完全依赖于它们的value属性的值,还会受到其他因素的影响,比如浏览器的渲染机制等。这种基于显示顺序的选中方式可能会带来一些不确定性,这就是所谓的模糊匹配。
至于React和其他库如anu、迷你版的preact或react-lite等,每个都有其独特的特点和适用场景。React无疑是当前最流行的前端库之一,它提供了丰富的功能和强大的社区支持。而其他库则可能在某些特定场景下提供更好的性能和体验。在使用这些工具时,我们需要根据自己的需求和项目的实际情况来做出选择。
学习和理解React中的select元素以及与之相关的匹配方式,对于每一个前端开发者来说都是非常重要的。我们也要对其他相关工具和库保持关注,以便在需要时能够做出明智的选择。狼蚁SEO希望大家能够通过这篇文章对React的select元素有更深入的理解,并希望大家能够多多支持狼蚁SEO,一起学习和进步。接下来,让我们继续React和其他前端技术的奥秘吧!
微信营销
- 浅谈React深度编程之受控组件与非受控组件
- 详解Js中的模块化是如何实现的
- jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
- 浅谈React Native 中组件的生命周期
- JS实现全屏的四种写法
- 浅谈React中的元素、组件、实例和节点
- php实现网页端验证码功能
- jQuery选择器之表单元素选择器详解
- koa+mongoose实现简单增删改查接口的示例代码
- 全面解析PHP面向对象的三大特征
- PHP使用反向Ajax技术实现在线客服系统详解
- jQuery表格插件datatables用法详解
- VUE组件中的 Drawer 抽屉实现代码
- 20个最常见的jQuery面试问题及答案
- vue路由教程之静态路由
- jQuery.extend 函数及用法详细