【react基础】5、state的使用和this指向

1、react的组件存放数据有两种方式。
(1)、存放外部数据的props,数据是只读,是不能修改的。
(2)、存放组件内部数据的state,存放组件自己的数据,其是放到constructor(){}里面。

2、关于constructor。
(1)constructor是先于render执行的
(2)constructor是什么时候调用?new的时候。new的时候做四件事:①新产生一个对象②让this指向新产生的对象③执行这个函数④会返回这个新创建的对象。

3、constructor里面的this
(1)在constructor里面直接输出this是不行的,会报错。
在这里插入图片描述
错误:this不被允许出现在super()之前。

(2)所以要用this得先写super()。
this是指向当前的实例,super是指向父类的实例,但是super()是调用父类的构造函数。
它是先实例化父类的实例 再实例化自己,不写super()得不到this。

但是以下写法可以得到this,但是得不到props。

constructor(){ //构造函数
	     super();
	     console.log(this.props)
}

要得到props可以在super()里面写super(props)

constructor(props){ //构造函数
	     super(props);
	     console.log(this.props)
	     console.log(props); //super里写了props后可以省去this
}

4、state用法
(1)写法

constructor(props){ 
	     super(props);
	     this.state = {  //存放组件本身的数据
	     	n:1,
	     	visible:true,
	     	arr:[1,2,3]
	     }
}

(2)修改state里面的值

①直接修改this.state.visible,这个方式会导致 数据会变,但是视图不会同步变,尽量避免用这种方式。

 class Group extends React.Component {
	        	constructor(props){
	        		super(props);
	        		this.state = {  //存放组件本身的数据
				     	n:1,
				     	visible:true,
				     	arr:[1,2,3]
				     }
	        		this.toggle = this.toggle.bind(this);  //toggle 能访问到this
	        	}
	        	toggle(){
	        			this.state.visible = !this.state.visible
	        			console.log(this.state.visible)
	        		})
	        	}
	        	render(){
	        		return <div>{this.state.visible}</div>
	        	}
	        }

解决方法:在toggle里面加一句this.forceUpdate()。但这种方式很不优雅,不推荐,最好永远不要用这种方式。

②使用setState({})语法,会改变state里面的值,触发render。

	<div id="box"></div>
	<script type="text/babel">
			class Demo extends React.Component {  //类组件 有state 
				constructor(props){
					super(props);
					this.state = {
						n:1
					}
					this.increment = this.increment.bind(this);
				}
				increment(){
					 this.setState({  //异步的
					n:this.state.n+1
					},()=>{
					console.log(this.state.n)
					})
				}
				render(){
					return <div> {this.state.n}
								<button onClick={this.increment}>+1</button>
								</div>
				}
			}
			var App = () =>{  //无状态组件
				return <div>
							<Demo />
						</div>
			}
			ReactDOM.render(<App />,document.querySelector("#box"));
	</script>

但是!!!
缺点:每次setState都会触发render,所以如果写两次setState按理说会有两次render,这个时候react不干了,因为每次都渲染效果效率会非常差劲。所以!它会把你两次的setState合并了!后面的会覆盖前面的,所以它只会执行最后一个操作。
不信可以执行下面的例子:

increment(){
		 	this.setState({  //异步的
			n:this.state.n+1
			},()=>{
			console.log(this.state.n)
			})
			this.setState({  //异步的
			// 	n:this.state.n+5
			},()=>{
				console.log(this.state.n)
			})
		}

为了解决要连续使用setState的问题,③方法诞生了。

③使用this.setState((prevState,props)=>{return {} })语法

increment(){
	 	this.setState((prevState,props)=>{
				return {
					n:prevState.n+1
				}
			})
			this.setState((prevState,props)=>{
				return {
					n:prevState.n+1
				}
			})
		}

此方法两个setState都会执行。因为这个setState()里面放的不是对象,而是函数。对象相同就会合并,但是函数是不会合并的,它们都会放到队列里面去依次执行。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值