React 入门:受控组件与非受控组件
文章目录
- 非受控组件
- 概念介绍
- 示例代码
- 受控组件
- 什么是受控组件
- 示例代码
- 代码优化
首先说明,我们基于表单数据的处理方式来理解受控组件与非受控组件。
非受控组件
概念介绍
非受控组件中,表单数据将交由 DOM 节点来处理,类似原生 JS 中获取 DOM 值的思路(document.getElementById("test")
)一样,只是在 React 是通过 Refs 来实现。
通俗的讲,对非受控组件而言,表单元素的值,是“随用随取”。
示例代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>非受控组件</title>
</head><body><!-- 准备好一个容器 --><div id="app"></div><!-- step01: 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- step02: 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- step03: 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel"> /* 此处一定要写babel */// 1. 创建类式组件class LoginForm extends React.Component {// 创建 ref 容器accountInputRef = React.createRef()passwordInputmyRef = React.createRef()handleSubmit = (event) => {event.preventDefault();const {accountInputRef, passwordInputmyRef} = thisconsole.log('@', `账号:${accountInputRef.current.value},密码:${passwordInputmyRef.current.value}`)}render() {return (<form onSubmit={this.handleSubmit}><p>账号:<input type="text" ref={this.accountInputRef} /></p><p>密码:<input type="password" ref={this.passwordInputmyRef} /></p><button>登录</button></form>)}}// 渲染组件到页面ReactDOM.render(<LoginForm />, document.getElementById('app'));</script></body></html>
受控组件
什么是受控组件
受控组件中,表单数据是由 React 组件中的 state 来管理的。也即是说受控组件就是受组件 state 的控制。
受控组件中的表单元素,需要绑定监听表单元素值变化的事件(通常是 onChange 事件),当表单元素的值发生变化时,将变化后的值更新到 state,当需要使用表单元素的值的时候,再通过 state 来取。
受控组件还有个特点,就是不使用 Refs 。
示例代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>受控组件</title>
</head><body><!-- 准备好一个容器 --><div id="app"></div><!-- step01: 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- step02: 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- step03: 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel"> /* 此处一定要写babel */// 1. 创建类式组件class LoginForm extends React.Component {// 初始化 statestate = { account: '', password: ''}// 保存账号到 statesaveAccount = (event) => {this.setState({account: event.target.value})}// 保存密码到 statesavePassword = (event) => {this.setState({password: event.target.value})}// 表单提交的回调handleSubmit = (event) => {event.preventDefault();const {account, password} = this.stateconsole.log('@', `账号:${account},密码:${password}`)}render() {return (<form onSubmit={this.handleSubmit}><p>账号:<input type="text" onChange={this.saveAccount} /></p><p>密码:<input type="password" onChange={this.savePassword} /></p><button>登录</button></form>)}}// 渲染组件到页面ReactDOM.render(<LoginForm />, document.getElementById('app'));</script></body></html>
上面的代码比较简单,仅用于示例演示。如果用于实际工作中,就会有问题,比如一个表单可能会有多个表单元素,那我们就需要写很多个 saveXxx 的事件绑定函数,这样写倒是也没错,只是比较麻烦,代码也不好维护。
代码优化
针对上面这个问题,接下来我们通过使用【高阶函数】和【函数的柯里化】对其进行优化来解决上面的问题。
先科普两个概念:
- 什么是高阶函数
如果一个函数符合下面 2 个规范中的任何一个,那该函数就是高阶函数。
- 若 A 函数,接收的参数是一个函数,那 A 就称之为高阶函数。
- 若 A 函数,调用的返回值依然是一个函数,那 A 就称之为高阶函数。
常见的高阶函数:Promise,setTimeout,arr.map()等。
- 什么是函数柯里化
通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。
处理后的代码如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>使用高阶函数和函数柯里化优化受控组件</title>
</head><body><!-- 准备好一个容器 --><div id="app"></div><!-- step01: 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- step02: 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- step03: 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel"> /* 此处一定要写babel */// 1. 创建类式组件class LoginForm extends React.Component {// 初始化 statestate = { account: '', password: ''}// 保存表单字段的值到 state,运用了高阶函数和函数的柯里化的技术saveFormData = (fieldName) => {return (event) => {this.setState({[fieldName]: event.target.value})}}// 表单提交的回调handleSubmit = (event) => {event.preventDefault();const {account, password} = this.stateconsole.log('@', `账号:${account},密码:${password}`)}render() {return (<form onSubmit={this.handleSubmit}><p>账号:<input type="text" onChange={this.saveFormData('account')} /></p><p>密码:<input type="password" onChange={this.saveFormData('password')} /></p><button>登录</button></form>)}}// 渲染组件到页面ReactDOM.render(<LoginForm />, document.getElementById('app'));</script></body></html>
React 入门:受控组件与非受控组件相关推荐
- [react] 受控组件和非受控组件有什么区别?
[react] 受控组件和非受控组件有什么区别? 受控组件用value和组件的state绑定,当value更新时,会自动更新state 非受控组件没有value,采用ref直接操作dom 个人简介 我 ...
- 深入react技术栈(10):受控组件和非受控组件
我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注前端小歌谣 受控组件 非受控组件 受控组件和非受控组件的区别 文章参考深入React技术栈
- React中受控组件和非受控组件
受控组件 在React中,每当表单的状态发生变化时,都会被写入到组件的state中,这种组件在React被称为受控组件.受控组件中,组件渲染的状态与它的value或者checked相对应.React通 ...
- React 之受控组件和非受控组件
在React中,所谓受控组件和非受控组件,是针对表单而言的. 表单受控组件 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似. 受控组件,表单元素的修改会实 ...
- 【React】之受控组件和非受控组件
React中的组件根据是否受React控制可分为受控的和非受控的. 一.受控组件 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似. 受控组件,表单元素的修 ...
- React的受控组件和非受控组件
一.受控组件 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似. 受控组件,表单元素的修改会实时映射到状态值上,此时就可以对输入的内容进行校验. 受控组件只 ...
- 【React】知识点归纳:受控组件与非受控组件区别
React: 受控组件与非受控组件区别 受控组件 示范代码: 原理图: 非受控组件 示范代码: 结论 受控组件 在HTML中,标签<input>.<textarea>.< ...
- 什么是React受控组件和非受控组件
React是一个非常流行的JavaScript库,用于构建Web应用程序.React中有两种类型的组件,受控组件和非受控组件.在本文中,我们将深入研究这两种组件的区别,优缺点以及如何选择适当的组件类型 ...
- React 的受控组件和非受控组件有什么不同
大家好,我是前端西瓜哥,今天我们来看看 React 的受控组件和非受控组件有什么不同. 受控组件 受控组件,指的是将表单元素的值交给组件的 state 来保存. 例子: import './style ...
最新文章
- 秋招必备:斩获腾讯offer的简历分享!
- php中strrpos函数的返回值类型是型_PHP常用函数总结
- html ppt文件在线播放,[2018年最新整理]如何在PPT中插入html网页.ppt
- JavaSE(二十)——面向对象的概念及三个基本特征
- 数据500%暴涨的神秘公式,顶级增长黑客如何实现用户指数级增长
- CRM, C4C和SAP Hybris的数据库层设计
- a标签href不跳转_[网页编程]-06 HTML5 超链接标签
- Mac OS使用技巧之三:发射无线网络信号的方法
- 使用Okta的单点登录保护您的Vert.x服务器
- 对中文语法的编程语言的质疑与回应
- 点击调试时提示MFC不包含调试信息
- 一则 Oracle 和 SqlServer 语法区别 (原创)
- 使用Adobe acrobat压缩pdf大小
- UIWebView 无缝切换到 WKWebView
- 推荐几本微积分入门书籍
- java:从入门到放弃(二)
- cs1.6服务器弹道优化,cs1.6弹道优化参数
- 在HTML网页中怎样写大于号和小于号
- 蓝云ERP系统项目笔记——库存预警(9)
- linux中ext3多重索引的原理,Ext3日志原理