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

不可控组件:直接通过底层的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. Bootstrap3 datetimepicker控件的使用

    Bootstrap3 日期+时间选择控件 1.支持日期选择,格式设定 2.支持时间选择 3.支持时间段选择控制 4.支持中文 官网地址:http://eonasdan.github.io/bootst ...

  2. spring整合springmvc和hibernate

    上篇文章使用maven搭建了web环境,这篇来记录下如何使用spring整合springmvc和hibernate,亦即spring+springmvc+hibernate框架整合. 第一步:首先配置 ...

  3. (译文)开始学习Webpack-应用TypeScript,配置热加载和Source Map

    项目初始化:采用TypeScript 我们的版本是: $ node --version v8.5.0 $ npm --version 5.5.1 npm版本升级了,因为npm最近带来了新特性,本地会生 ...

  4. RabbitMQ封装实战

    先说下背景:上周开始给项目添加曾经没有过的消息中间件.虽然说,一路到头非常容易,直接google,万事不愁~可是生活远不仅是眼前的"苟且".首先是想使用其他项目使用过的一套对mq封 ...

  5. JAVA设计模式之【装饰者模式】

    JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...

  6. 2017-2018-1 Java演绎法 第八周 作业

    团队任务:UML设计 团队组长:袁逸灏 本次编辑:刘伟康 团队分工 第一次使用泳道图,感觉非常方便,从图中的箭头和各个活动框中可以清晰地看出分工流程: 不过既然是博客园,分工就不能只贴图,markdo ...

  7. Linux下C编写基本的多线程socket服务器

    不想多说什么,会搜这些东西的都是想看代码的吧. 一开始不熟悉多线程的时候还在想怎么来控制一个线程的结束,后来发现原来有pthread_exit()函数可以直接在线程函数内部调用结束这个线程. 开始还想 ...

  8. 算法第四版 coursera公开课 普林斯顿算法 ⅠⅡ部分 Robert Sedgewick主讲《Algorithms》

    这是我在网上找到的资源,下载之后上传到我的百度网盘了. 包含两部分:1:算法视频的种子 2:字幕 下载之后,请用迅雷播放器打开,因为迅雷可以直接在线搜索字幕. 如果以下链接失效,请在下边留言,我再更新 ...

  9. idea 导eclipse项目

    https://www.cnblogs.com/xiaoBlog2016/archive/2017/05/08/6825014.html

  10. datable转xml

    /// <summary> /// datatable转换xml /// </summary> /// <param name="xmlDS"> ...