react可控组件和不可控组件
原创
©著作权归作者所有:来自51CTO博客作者wx5c4a6751206d9的原创作品,请联系作者获取转载授权,否则将追究法律责任
在React中的input标签是有些小坑的,input本身就有自己的缓存机制,然后React的State也有缓存机制。这两种缓存机制我们在编码中是要进行取舍的。将input中的value绑定到state的React组件就是可控组件,反之则是不可控组件。
先看一个不可控的input代码
//测试效果用
import React, { Component } from 'react';
class MyForm extends Component {
constructor(props) {
//super指代父类的实例(即父类的this对象)
super(props);
this.state = {
username: '',
gender: 'man',
checked: true,
value: 'ferrysoul'
};
}
getInitialState(){
return { value: 'ferrysoul' }
};
handleChange(event) {
this.setState({ value: event.target.value });
console.log(this.state.value)
};
render() {
return (
<div>
<input type="text" value={this.state.value} />
</div>
)
}
}
export default MyForm;
不可控的input无法改变值,不管你怎么敲击键盘输入,input中的数值不会发生任何改变,打开控制台会有一个报错信息,
原因是:
因为input标签,没有定义onChange 但是提供了value属性。React会抛出警告,并将元素设置为只读。
如果目标是只读字段,最好使用readOnly属性明确加以定义。这不仅会消除警告,也会确保代码的可读性。
解决:
可以添加readOnly={true} ,或者直接添加readOnly属性,而不设置值,React会默认将该属性的值设为true。
一。设置onchang,变成可控input
(1)直接在函数后面.bind(this)
//测试效果用
import React, { Component } from 'react';
class MyForm extends Component {
constructor(props) {
//super指代父类的实例(即父类的this对象)
super(props);
this.state = {
username: '',
gender: 'man',
checked: true,
value: 'ferrysoul'
};
}
getInitialState(){
return { value: 'ferrysoul' }
};
handleChange(event) {
console.log(event.target.value)
this.setState({ value: event.target.value });
console.log(this.state.value)
};
render() {
return (
<div>
<input type="text" value={this.state.value} onChange={this.handleChange.bind(this)} />
<p>显示你的value如下:</p>
<p>{this.state.value}</p>
</div>
)
}
}
export default MyForm;
(2.)在constructor中绑定this,在render中调用的时候就不需要bind了,直接 this.函数名
//测试效果用
import React, { Component } from 'react';
class MyForm extends Component {
constructor(props) {
//super指代父类的实例(即父类的this对象)
super(props);
this.state = {
username: '',
gender: 'man',
checked: true,
value: 'ferrysoul'
};
this.handleChange = this.handleChange.bind(this);
}
getInitialState(){
return { value: 'ferrysoul' }
};
handleChange(event) {
console.log(event.target.value)
this.setState({ value: event.target.value });
console.log(this.state.value)
};
render() {
return (
<div>
<input type="text" value={this.state.value} onChange={this.handleChange} />
<p>显示你的value如下:</p>
<p>{this.state.value}</p>
</div>
)
}
}
export default MyForm;
(3).直接使用箭头函数:这种适用于函数块代码比较少的情况
//测试效果用
import React, { Component } from 'react';
class MyForm extends Component {
constructor(props) {
//super指代父类的实例(即父类的this对象)
super(props);
this.state = {
username: '',
gender: 'man',
checked: true,
value: 'ferrysoul'
};
}
getInitialState(){
return { value: 'ferrysoul' }
};
// handleChange(event) {
// console.log(event.target.value)
// this.setState({ value: event.target.value });
// console.log(this.state.value)
// };
render() {
return (
<div>
<input type="text" value={this.state.value} onChange={(event) => { this.setState({ value: event.target.value });}} />
<p>显示你的value如下:</p>
<p>{this.state.value}</p>
</div>
)
}
}
export default MyForm;
二。依旧是不可控input,但是没有报错的问题了
//测试效果用
import React, { Component } from 'react';
class MyForm extends Component {
constructor(props) {
//super指代父类的实例(即父类的this对象)
super(props);
this.state = {
username: '',
gender: 'man',
checked: true,
value: 'ferrysoul'
};
}
getInitialState(){
return { value: 'ferrysoul' }
};
render() {
return (
<div>
<input type="text" value={this.state.value} readOnly={true} />
<p>显示你的value如下:</p>
<p>{this.state.value}</p>
</div>
)
}
}
export default MyForm;
----------------------------------------------------------------------------------------------------------
在input标签中不把value绑定到state上的就是不可控组件,它的数据不合state对应,所以在开发时会给自己挖很多坑,但是不可控组件并不是不可掌控,就用一节课的时间,我们了解一下不可控组件的小技巧。
组件完成之后给它加上一个onChange事件,发现是可以监控到变化值的。如果要获得iput中的value值,需先拿到其DOM节点,然后获取其value值。
//测试效果用
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class MyForm extends Component {
constructor(props) {
//super指代父类的实例(即父类的this对象)
super(props);
this.state = {
username: '',
gender: 'man',
checked: true,
value: 'ferrysoul'
};
this.handleChange = this.handleChange.bind(this);
}
getInitialState(){
return { value: 'ferrysoul' }
};
handleChange(event) {
var inputValue = ReactDOM.findDOMNode(this.refs.ferrysoul).value;
console.log(inputValue);
this.setState({ value: event.target.value });
};
render() {
return (
<div>
<input type="text" value={this.state.value} ref="ferrysoul" onChange={this.handleChange} />
<p>显示你的value如下:</p>
<p>{this.state.value}</p>
</div>
)
}
}
export default MyForm;