学习React系列(四)——受控组件与非受控组件
2024-10-15 12:19:25
受控组件:通过组件的状态与属性的改变来控制组件
不可控组件:直接通过底层的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/
最新文章
- linux 安装maven
- 屏蔽input导致的回车提交事件
- Zabbix discoverer processes more than 75% busy
- HTTP refere
- 12、android socket使用demo:网络聊天
- Microsoft.AspNet.FriendlyUrls发布到IIS后404报错的解决方案
- PyCharm使用技巧记录(一)如何查看变量
- openStack云平台虚拟桌面galera mysql 3节点集群实例实战 调试完成
- 解决IE6,IE7不能隐藏绝对定位溢出的内容
- IBM X System ServerGuide 8.41 服务器 系统安装 引导盘
- asp.net MVC Session锁的问题
- sonarqube+Scanner代码质量管理工具
- MySQL/MariaDB中游标的使用
- Maven发布jar包到私库
- HDU 2511 汉诺塔X
- zedgraph控件的一些比较有用的属性 转
- Algorithms: Design and Analysis, Part 1 - Programming Assignment #1
- Mysql利用binlog日志恢复数据操作(转)
- AJAX 过程总结
- 基于Html5的爱情主题网站–表白神器