受控组件和非受控组件
受控组件和非受控组件
React
的受控组件与非受控组件的概念是相对于表单而言的,在React
中表单元素通常会持有一下内部的state
,因此它的工作方式与其他HTML
元素不一样,而获取表单元素内部state
的实现方式的不同,就产生了受控组件和非受控组件。
受控组件
在HTML
的表单元素中,它们通常自己维护一套state
,并随着用户的输入自己进行UI
上的更新,这种行为是不被我们程序所管控的,而如果将React
里的state
属性和表单元素的值建立依赖关系,再通过onChange
事件与setState()
结合更新state
属性,就能达到控制用户输入过程中表单发生的操作,React
以这种方式控制取值的表单输入元素就叫做受控组件。
在React
中定义了一个input
输入框的话,它并没有类似于Vue
里v-model
的这种双向绑定功能,也就是说我们并没有一个指令能够将数据和输入框结合起来,用户在输入框中输入内容,然后数据同步更新。
class Input extends React.Component {render () {return <input name="username" />}
}
用户在界面上的输入框输入内容时,它是自己维护了一个state
,这个state
并不是我们平常看见的this.state
,而是每个表单元素上抽象的state
,这样的话就能根据用户的输入自己进行UI
上的更新,如果我们想要控制输入框的内容,而输入框的内容取决的是input
中的value
属性,那么我们可以在this.state
中定义一个名为username
的属性,并将input
上的value
指定为这个属性。
class Input extends React.Component {constructor (props) {super(props);this.state = { username: "1" };}render () {return <input name="username" value={this.state.username} />}
}
但是这时候你会发现input
的内容是只读的,因为value
会被我们的this.state.username
所控制,当用户输入新的内容时,this.state.username
并不会自动更新,这样的话input
内的内容也就不会变了,此时控制台通常会抛出一个Warning
。
Warning: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
您为表单字段提供了一个没有onChange
处理程序的value
属性,这将呈现只读字段,如果字段应该是可变的,请使用defaultValue
,否则请设置onChange
或readOnly
。
这段Warning
其实给出了对于这个问题的解决方案,我们只需要对组件的onChange
事件来监听输入内容的改变并使用setState
更新this.state.username
即可,如此我们在当前组件中能够控制这个表单元素的值,这就是受控组件。
class Input extends React.Component {constructor (props) {super(props);this.state = { username: "1" };}render () {return (<><input name="username" value={this.state.username} onChange={e => this.setState({username: e.target.value})} /><button onClick={() => console.log(this.state.username)} >Log</button></>)}
}
此外需要注意的是,如果是讲此组件作为一个共用的组件用以调用的话,是有弊端的,尽管此时Input
组件本身是一个受控组件,但与之相对的调用方失去了更改Input
组件值的控制权,所以对调用方而言,Input
组件是一个非受控组件,以非受控组件的使用方式去调用受控组件是一种反模式,下边的例子都是属于Hooks
的写法。
// 组件提供方
function Input({ defaultValue }) {const [value, setValue] = React.useState(defaultValue)return <input value={value} onChange={e => setValue(e.target.value)} />
}// 调用方
function UseInput() {return <Input defaultValue={1} />
}
如果要对于组件提供方还是调用方Input
组件都为受控组件,只需要提供方让出控制权即可。
// 组件提供方
function Input({ value, onChange }) {return <input value={value} onChange={onChange} />
}// 调用方
function UseInput() {const [value, setValue] = React.useState(1);return <Input value={value} onChange={e => setValue(e.target.value)} />
}
非受控组件
如果表单元素并不经过state
,而是通过ref
修改或者直接操作DOM
,那么它的数据无法通过state
控制,这就是非受控组件。
class Input extends React.Component {constructor (props) {super(props);this.input = React.createRef();}render () {return (<><input name="username" ref={this.input} /><button onClick={() => console.log(this.input.current.value)} >Log</button></>)}
}
总结
受控组件
- 每当表单的状态发生变化时,都会被写入到组件的
state
中。 - 在受控组件中,组件渲染出的状态与它的
value
或checked prop
相对应。 react
受控组件更新state
的流程:- 通过在初始
state
中设置表单的默认值。 - 每当表单的值发生变化时,调用
onChange
事件处理器。 - 事件处理器通过合成对象
event
拿到改变后的状态,并更新应用的state
。 SetState
触发视图的重新渲染,完成表单组件值的更新。
- 通过在初始
非受控组件
- 如果一个表单组件没有
value prop
就可以称为非受控组件。 - 非受控组件是一种反模式,它的值不受组件自身的
state
或props
控制。 - 通常需要为其添加
ref prop
来访问渲染后的底层DOM
元素。 - 可通过添加
defaultValue
指定value
值。
每日一题
https://github.com/WindrunnerMax/EveryDay
参考
https://muyunyun.cn/posts/8bdf2cdf/
https://zhuanlan.zhihu.com/p/89223413
https://juejin.cn/post/6844904154133954568
https://juejin.cn/post/6858276396968951822
https://segmentfault.com/a/1190000022925043
https://segmentfault.com/a/1190000012458996
https://zh-hans.reactjs.org/docs/glossary.html
受控组件和非受控组件相关推荐
- [react] 受控组件和非受控组件有什么区别?
[react] 受控组件和非受控组件有什么区别? 受控组件用value和组件的state绑定,当value更新时,会自动更新state 非受控组件没有value,采用ref直接操作dom 个人简介 我 ...
- 深入react技术栈(10):受控组件和非受控组件
我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注前端小歌谣 受控组件 非受控组件 受控组件和非受控组件的区别 文章参考深入React技术栈
- React中受控组件和非受控组件
受控组件 在React中,每当表单的状态发生变化时,都会被写入到组件的state中,这种组件在React被称为受控组件.受控组件中,组件渲染的状态与它的value或者checked相对应.React通 ...
- React 之受控组件和非受控组件
在React中,所谓受控组件和非受控组件,是针对表单而言的. 表单受控组件 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似. 受控组件,表单元素的修改会实 ...
- React-表单处理(受控组件,非受控组件)
受控组件: value值受到了react状态控制的表单元素 React中将state中的数据与表单元素的value值绑定到了一起,由state的值来控制表单元素的值 非受控组件: 非受控组件借助于re ...
- React---什么是受控组件、非受控组件
受控组件: 在随后的用户输入中,能够控制表单中输入元素的组件被称为受控组件,即每个状态更改都有一个相关联的处理程序. 例如,我们使用下面的 handleChange 函数将输入框的值转换成大写: ha ...
- 【React】之受控组件和非受控组件
React中的组件根据是否受React控制可分为受控的和非受控的. 一.受控组件 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似. 受控组件,表单元素的修 ...
- 【REACT-受控组件和非受控组件】
REACT-受控组件和非受控组件 概述 受控组件 非受控组件 受控组件应用ToDoList 概述 React中的组件根据是否受React控制可分为受控的和非受控的. React 中的受控组件和非受控组 ...
- React的受控组件和非受控组件
一.受控组件 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似. 受控组件,表单元素的修改会实时映射到状态值上,此时就可以对输入的内容进行校验. 受控组件只 ...
最新文章
- 无需写代码的高颜值富集分析神器
- 信号系统的一些基本概念
- 教程-MessageBox 使用方法
- 学python需要英语基础吗-学python需要英语基础吗
- 利用 Android Studio 和 Gradle 打包多版本APK
- P6282 [USACO20OPEN] Cereal S 思维
- Linux下的TCP/IP编程----IO复用及IO复用服务端
- [UE4] AnimationBlueprint: Node XXX uses potentially thread-unsafe call XXX 的解决办法,get 静态对象
- 单列(写了池子pool)用list实现的方法, 与伪单例(写了池子zidianpool),用字典实现的方法,可以存入不同,i名字的物体...
- IDEA 插件 Material Theme UI收费后 免费的办法
- winform 可拖动的自定义Label控件
- 用友U8安装...(转)
- 玩转C语言Socket网络编程
- 怎么管理员工混工时的现象?
- 通过二进制逻辑运算解题
- 真西游记java,原来《西游记》原著真的很吓人,我们都被86版西游记骗了?
- ■ 直接调用阿里云视频点播API实现视频播放
- icp增值电信业务许可证办理条件及流程介绍
- oracle执行计划耗费 基数 字节,Oracle 查看执行计划
- win10系统访问局域网服务器,Win10系统不能访问局域网共享磁盘的解决方法