react可控组件和不可控组件

在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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值