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

不可控组件:直接通过底层的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. werkzeug(flask)中的local,localstack,localproxy探究

    1.关于local python中有threading local处理方式,在多线程环境中将变量按照线程id区分 由于协程在Python web中广泛使用,所以threading local不再满足需 ...

  2. 从零部署Spring boot项目到云服务器(正式部署)

    上一篇文章总结了在Linux云服务器上部署Spring Boot项目的准备过程,包括环境的安装配置,项目的打包上传等. 链接在这里:http://www.cnblogs.com/Lovebugs/p/ ...

  3. Alpha冲刺Day2

    Alpha冲刺Day2 一:站立式会议 今日安排: 首先完善前一天的剩余安排工作量,其次我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.数据管理员这一模块,数据管理员又可细分为 ...

  4. django搭建web (一)

    建立工程 django-admin.py startproject project_name 建立app python manage.py startapp app_name 将app添加进工程中 在 ...

  5. 201621123043《java程序设计》第4周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键字:继承.覆盖.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 1.3 可选:使用 ...

  6. 【iOS】swift-ObjectC 在iOS 8中使用UIAlertController

    iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.全新的UIPresentationController在实现视图控制器间的过渡动画效果和自适应设备尺寸 ...

  7. Struts2之配置文件中Action的详细配置

    在Struts2之配置一文中,我们知道一个struts配置文件可以分为三部分:常量配置    包含其他配置文件的配置    Action配置  . 这其中 常量配置  和 包含其他配置文件的配置  二 ...

  8. 一句话了解JAVA与大数据之间的关系

    大数据无疑是目前IT领域的最受关注的热词之一.几乎凡事都要挂上点大数据,否则就显得你OUT了.如果再找一个可以跟大数据并驾齐驱的IT热词,JAVA无疑是跟大数据并驾齐驱的一个词语.很多人在提到大数据的 ...

  9. 一个页面多个HTTP请求 页面卡顿!

    用promise解决 前两天面试的时候 一个面试官问到这样一个问题 这里先说出解决的路径 这几天会更新具体的做法 或者直接参考廖雪峰大神 地址如下: https://www.liaoxuefeng.c ...

  10. eclipse maven项目目录

    今天遇见一个错误,关于eclipse项目的路径问题,web-inf的路径,上图和下图出现了两种web-INF,src的web-INFf和webContent的web-INF,src里面的文件需要编译以 ...