-
受控组件:组件的使用者,有能力完全控制该组件的行为和内容;通常情况下,受控组件往往没有自身的状态,其内容完全受到属性的控制 (表单组件,默认情况下是非受控组件,一旦设置了表单组件的 value 属性,则其变为受控组件,单选和多选框需要设置 checked);
-
非受控组件:组件的使用者,没有能力控制该组件的行为和内容,组件的行为和内容完全自行控制;
受控组件(推荐)
优势
预测性:由于组件的值是由 React 的状态控制的,因此当状态变化时,组件的行为是可预测的;
可控性:开发者可以精确地控制组件的值,这在处理复杂的用户交互和数据流时非常有用;
组件复用:受控组件可以轻松地在不同的上下文中复用,因为它们的值和行为完全由父组件控制;
局限
额外的样板代码:使用受控组件通常需要编写额外的代码来处理状态的更新;
性能问题:在某些情况下,过度使用受控组件可能会导致不必要的渲染,影响性能;
基本使用
// input 表单处理
class InputComponent extends React.Component {
constructor(props) {
super(props);
this.state = { value: "Hello Ricepudding!" };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
render() {
var value = this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<h4>{value}</h4>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<InputComponent />);
// select 表单处理
class SelectComponent extends React.Component {
constructor(props) {
super(props);
this.state = { value: "coconut" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
console.log(this.state);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
选择您最喜欢的网站
<select value={this.state.value} onChange={this.handleChange}>
<option value="tb">Taobao</option>
<option value="fb">Facebook</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<SelectComponent />);
// 多个表单元素处理
class MultiFormComponent extends React.Component {
state = {
loginId: "",
loginPwd: "",
sex: "male",
chooseLoves: [],
loves: [
{ value: "football", text: "足球" },
{ value: "basetball", text: "篮球" },
{ value: "movie", text: "电影" },
{ value: "music", text: "音乐" },
{ value: "other", text: "其他" },
],
city: "beijing"
}
handleChange = e => {
let val = e.target.value; //读取表单的值
let name = e.target.name; //读取表单的name属性
if (e.target.type === "checkbox") {
//对val进行特殊处理
if (e.target.checked) {
val = [...this.state.chooseLoves, val];
}
else {
val = this.state.chooseLoves.filter(it => it !== val);
}
}
this.setState({
[name]: val
})
}
/**
* 获取所有的爱好 多选框
*/
getLoveCheckBoxes() {
const bs = this.state.loves.map(it => (
<label key={it.value} >
<input type="checkbox" name="chooseLoves"
value={it.value}
checked={this.state.chooseLoves.includes(it.value)}
onChange={this.handleChange}
/>
{it.text}
</label>
));
return bs;
}
render() {
const bs = this.getLoveCheckBoxes();
return (
<div>
<p>
<input type="text" name="loginId" value={this.state.loginId} onChange={this.handleChange} />
</p>
<p>
<input type="password" name="loginPwd" value={this.state.loginPwd} onChange={this.handleChange} />
</p>
<p>
<label>
<input type="radio" name="sex" value="male" checked={this.state.sex === "male"} onChange={this.handleChange} />
男
</label>
<label>
<input type="radio" name="sex" value="female" checked={this.state.sex === "female"} onChange={this.handleChange} />
女
</label>
</p>
<p>
{bs}
</p>
<p>
<select name="city" value={this.state.city} onChange={this.handleChange} >
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="chengdu">成都</option>
</select>
</p>
<p>
<button onClick={() => { console.log(this.state) }}>获取表单数据</button>
</p>
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<MultiFormComponent />);
非受控组件
优势
简洁性:使用非受控组件可以减少样板代码,使得代码更加简洁;
性能:在某些情况下,非受控组件可以提高性能,因为它们不需要在每次值变化时触发状态更新和组件重渲染;
局限
不可预测性:由于 React 不控制非受控组件的值,因此在某些复杂的场景下,组件的行为可能变得不可预测;
难以管理:在复杂的应用中,非受控组件可能导致难以追踪和管理的状态;
基本使用
class UnControlComponent extends React.Component {
constructor(props) {
super(props);
this.usernameRef = React.createRef();
}
handleSubmit(event) {
event.preventDefault();
console.log(this.usernameRef.current.value);
}
render() {
return (
<div>
<form onSubmit={(e) => this.handleSubmit(e)}>
<label htmlFor="">
用户:
<input defaultValue="username" type="text" name="username" ref={this.usernameRef} />
</label>
<input type="submit" value="提交" />
</form>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<UnControlComponent />);
React✍️ Ref、Ref 转发
上一篇