受控组件:通过组件的状态与属性的改变来控制组件

不可控组件:直接通过底层的dom来控制组件(具体来说就是通过绑定再底层dom上的方法来实现的,比如说ref,onChange)

受控组件

function validate(name, email, password) {
// we are going to store errors for all fields
// in a signle array
const errors = []; if (name.length === 0) {
errors.push("Name can't be empty");
} if (email.length < 5) {
errors.push("Email should be at least 5 charcters long");
}
if (email.split('').filter(x => x === '@').length !== 1) {
errors.push("Email should contain a @");
}
if (email.indexOf('.') === -1) {
errors.push("Email should contain at least one dot");
} if (password.length < 6) {
errors.push("Password should be at least 6 characters long");
} return errors;
} class SignUpForm extends React.Component {
constructor() {
super();
this.state = {
name: '',
email: '',
password: '', errors: [],
}; this.handleSubmit = this.handleSubmit.bind(this);
} handleSubmit(e) {
e.preventDefault(); const { name, email, password } = this.state; const errors = validate(name, email, password);
if (errors.length > 0) {
this.setState({ errors });
return;
} // submit the data...
} render() {
const { errors } = this.state;
return (
<form onSubmit={this.handleSubmit}>
{errors.map(error => (
<p key={error}>Error: {error}</p>
))}
<input
value={this.state.name}
onChange={evt => this.setState({ name: evt.target.value })}
type="text"
placeholder="Name"
/>
<input
value={this.state.email}
onChange={evt => this.setState({ email: evt.target.value })}
type="text"
placeholder="Email"
/>
<input
value={this.state.password}
onChange={evt => this.setState({ password: evt.target.value })}
type="password"
placeholder="Password"
/> <button type="submit">Submit</button>
</form>
);
}
} ReactDOM.render(<SignUpForm />, document.body);

不可控组件

function validate(name, email, password) {
// we are going to store errors for all fields
// in a signle array
const errors = []; if (name.length === 0) {
errors.push("Name can't be empty");
} if (email.length < 5) {
errors.push("Email should be at least 5 charcters long");
}
if (email.split('').filter(x => x === '@').length !== 1) {
errors.push("Email should contain a @");
}
if (email.indexOf('.') === -1) {
errors.push("Email should contain at least one dot");
} if (password.length < 6) {
errors.push("Password should be at least 6 characters long");
} return errors;
} class SignUpForm extends React.Component {
constructor() {
super();
this.state = {
errors: [],
}; this.handleSubmit = this.handleSubmit.bind(this);
} handleSubmit(e) {
e.preventDefault(); const name = ReactDOM.findDOMNode(this._nameInput).value;
const email = ReactDOM.findDOMNode(this._emailInput).value;
const password = ReactDOM.findDOMNode(this._passwordInput).value; const errors = validate(name, email, password);
if (errors.length > 0) {
this.setState({ errors });
return;
} // submit the data...
} render() {
const { errors } = this.state;
return (
<form onSubmit={this.handleSubmit}>
{errors.map(error => (
<p key={error}>Error: {error}</p>
))}
<input
ref={nameInput => this._nameInput = nameInput}
type="text"
placeholder="Name"
/>
<input
ref={emailInput => this._emailInput = emailInput}
type="text"
placeholder="Email"
/>
<input
ref={passwordInput => this._passwordInput = passwordInput}
type="password"
placeholder="Password"
/> <button type="submit">Submit</button>
</form>
);
}
} ReactDOM.render(<SignUpForm />, document.body);

在使用非受控组件的时候可以通过设置默认值来对dom的value进行初始化操作

class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
} handleSubmit(event) {
alert('A name was submitted: ' + this.input.value);
event.preventDefault();
} render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
defaultValue="Bob"
type="text"
ref={(input) => this.input = input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}

另外, <input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked<select> 和<textarea> 支持 defaultValue.

访问文件的实例(非控制组件)

class FileInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${this.fileInput.files[0].name}`
);
} render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input
type="file"
ref={input => {
this.fileInput = input;
}}
/>
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
} ReactDOM.render(
<FileInput />,
document.getElementById('root')
);

他们的应用场景对比:

结论:尽可能的使用受控组件来进行表单提交的操作,除非符合本文中给出的不可控例子或者为单次提交检验的form操作。(不可控实现的原理其实就是在ref的回掉中把当前的dom对象赋给组件的某个属性,通过该属性进而操作dom对象)

参考:https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/

https://reactjs.org/docs/uncontrolled-components.html

学习React系列(四)——受控组件与非受控组件的更多相关文章

  1. React:受控组件与非受控组件混用实战 - 译文

    原文链接:React: hybrid controlled components in action 受控组件 非受控组件 混用受控组件和非受控组件 原则一 原则二 原则三 原则四 实施方案 总结 F ...

  2. 浅谈react受控组件与非受控组件

    引言 最近在使用蚂蚁金服出品的一条基于react的ant-design UI组件时遇到一个问题,编辑页面时input输入框会展示保存前的数据,但是是用defaultValue就是不起作用,输入框始终为 ...

  3. React受控组件和非受控组件

    受控组件和非受控组件主要是用来解决表单组件状态谁来控制的问题.因为用户的输入会反应在界面上,相当于视图的状态发生了变化,而react是通过虚拟DOM比对修改视图的,这里就要决定谁来控制表单组件的状态. ...

  4. react 表单(受控组件和非受控组件)

    我们知道表单元素与其他的普通DOM元素来说是不一样的,它们保存了自己的一些状态. 我们主要说的就是表单元素中的受控组件和非受控组件. 受控组件就是这个组件的状态是我们(react)控制的,这个组件的行 ...

  5. react中 受控组件和 非受控组件 浅析

    一 受控组件 顾名思义,受控 也就是能够被控制,简而言之也就是 该组件ui的显示或者内部state逻辑的变化依赖外部的 props的传入. 二 非受控组件 顾名思义,非受控,也就是内部的视图变化,st ...

  6. react第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能)

    第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能) #课程目标 理解因为react的单向数据流 理解表单组件会因为react数据流变的不好维护 理解受控组件与非受控组件的实质区别 理解 ...

  7. Vue父子组件及非父子组件如何通信

    1.父组件传递数据给子组件 父组件数据如何传递给子组件呢?可以通过props属性来实现 父组件: 子组件通过props来接收数据: 方式1: 方式2 : 方式3: 这样呢,就实现了父组件向子组件传递数 ...

  8. React文档(十七)非受控组件

    大多数情况下,我们建议使用受控组件(也就是用React的state来控制表单元素的value值)来实现表单.在一个受控组件里,表单数据被React组件处理.另一种方案就是非控制组件,这样的话表单数据就 ...

  9. React 受控组件和非受控组件

    需求用户名自动获取 onChange用户状态发生改变 就获取值 就是时时获取值 使用onChange 点击按钮 获取密码 只要绑定了点击事件 就可以获取值 通过 let usercont=event. ...

随机推荐

  1. Oracle查询优化改写--------------------高级查询

    一.给结果集分页 二.重新生成房间号 三.跳过表中n行 四.排列组合去重

  2. 爬虫(scrapy中调试文件)

    在项目setting同级目录下创建py文件,代码如下: from scrapy.cmdline import execute import sys import os sys.path.append( ...

  3. Suricata默认规则集相关

    Suricata规则集 Suricata 基于规则检测和控制数据流量,所有规则的配置文件保存在rules目录内 .这些是已知和确认的活动僵尸网络和其C&C(command and contro ...

  4. 去除input的自动填充色

    input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px #ffffff inset !important; }

  5. php设计模式七 ---组合模式

    1.介绍 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...

  6. 多目标跟踪(MOT)论文随笔-SIMPLE ONLINE AND REALTIME TRACKING (SORT)

    网上已有很多关于MOT的文章,此系列仅为个人阅读随笔,便于初学者的共同成长.若希望详细了解,建议阅读原文. 本文是使用 tracking by detection 方法进行多目标跟踪的文章,是后续de ...

  7. 【java并发系列】Fork/Join任务(转)

    原文链接 当我们需要执行大量的小任务时,有经验的Java开发人员都会采用线程池来高效执行这些小任务.然而,有一种任务,例如,对超过1000万个元素的数组进行排序,这种任务本身可以并发执行,但如何拆解成 ...

  8. 201621123057 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现什 ...

  9. org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be res

    解决:web项目出现如上问题,据查是版本问题: JSTL 1.0 的声明是: <%@ taglib prefix="c" uri="http://java.sun. ...

  10. 团队作业7——第二次项目冲刺(Beta版本12.05-12.07)

    1.当天站立式会议照片 本次会议内容:1:每个人汇报自己完成的工作.2:组长分配各自要完成的任务. 2.每个人的工作 黄进勇:项目整合,后台代码. 李勇:前台界面优化. 何忠鹏:数据库模块. 郑希彬: ...