STATE

state

import React, { Component } from 'react';

class Count extends Component{
	 constructor(props){
	 	super(props);
	 	this.state={count:0};
	 	this.increase=this.increase.bind(this);
	 	this.decrease=this.decrease.bind(this)
	 	this.add=this.add.bind(this)
	 }
	 
	 add(){
	 	this.state.count=this.state.count+1
	 	console.log(this.state.count)
			
	 }

	 increaseSelf(){
	 	for(let i=0;i<1000;i++){
	 		console.log(i)
	 		this.setState({
	 		count:this.state.count+1
	 	})
	 	}
	 }

	 increase(){
		this.setState({
			count:this.state.count+1
	 	})
	 }

	 decrease(){
	 	this.setState({
	 		count:this.state.count-1
	 	})
	 }
	 
	 render(){
	 	console.log('********组件渲染*********')
	 	return(
	 		<div style={{margin:"100px"}}>
		 		<span>{this.state.count}</span>
		 		<button onClick={this.add}>add</button>
		 		<button onClick={this.increase}>increase</button>
		 		<button onClick={this.increase}>decrease</button>
	 		</div>
	 	)
	 }
}

class App extends Component {
  render() {
    return (
      <Count/>
    );
  }
}

export default App;

1.直接修改state,点击add按钮5次,依次打印1,2,3,4,5,但是页面上显示仍然是0,虽然修改了state,但不会渲染组件。

2.点击add按钮5次,一次打印1,2,3,4,5,页面上显示仍然是0,此时点击increase按钮,页面数字变成6.

修改increase()函数

	 increase(){
		this.setState({
			count:this.state.count+1
	 	})
		this.setState({
	 		count:this.state.count+2
	 	})
	 	this.setState({
	 		count:this.state.count+3
	 	})
	 
	 }

点击increase按钮,页面数字变成3。这是因为当前state.count的值是0,执行第一个setState()函数,将{count:0+1}映射到待执行队列,执行第二个setState()函数,将{count:0+2}映射到待执行队列,后执行的setState将覆盖掉前面的,最后一个是有效的。待执行队列中的count的值是3,执行更新。

如果改变三个setState()函数的顺序,最后一个有效。下列代码点击increase按钮,数字变成2

increase(){
		this.setState({
			count:this.state.count+1
	 	})
		
	 	this.setState({
	 		count:this.state.count+3
	 	})
	 	this.setState({
	 		count:this.state.count+2
	 	})

修改increase()函数,点击increase按钮,数字变成6,执行前三个setState()函数时,最后一个有效,待执行队列中的count的值是3,当setState的参数是函数时,prevState的值从待执行队列中取得,所以最终结果是6。

	 increase(){
		this.setState({
			count:this.state.count+1
	 	})
	 	
	 	this.setState({
	 		count:this.state.count+2
	 	})
	 	this.setState({
	 		count:this.state.count+3
	 	})
	 	this.setState((prevState, props)=>{return{count:prevState.count+1}})
	 	this.setState((prevState, props)=>{return{count:prevState.count+1}})
	 	this.setState((prevState, props)=>{return{count:prevState.count+1}})

	 
	 }

修改increase()函数,每点击一次,数字加1,不管点击速度有多快

	 increase(){
		this.setState({
			count:this.state.count+1
	 	})
	 }

修改increase()函数

	 increase(){
		this.increaseSelf()
	 }

从上面的两种情况可以猜测,待执行队列的执行时机,根据用户的行为,用户的一次操作,可能执行很多setState()函数,但是执行队列只执行一次。

 

修改increase()函数,点击increase按钮,数字变成2,setTimeout()也可以执行一次待执行队列(本质是setTimeout执行时,isBatchingUpdates是false)。实际上执行了两次render()函数。

	 increase(){
		this.setState({
	 		count:this.state.count+1
	 	})
		setTimeout(()=>this.setState({
	 		count:this.state.count+1
	 	}),0)
	 }

修改increase()函数,点击increase按钮,数字变成2,setTimeout()函数中的所有setState()都是同步执行,本质是isBatchingUpdates的值是false。

	 increase(){
		setTimeout(()=>{
			this.setState({
	 			count:this.state.count+1
	 		});
			this.setState({
	 			count:this.state.count+1
	 		});
		},0)
	 }

replaceState()和setState()的区别

比如现在state的结构是

state={
 name:"Jack"
 age:18
}

执行setState({name:"Tom"}),后

state={
 name:"Tom"
 age:18
}

如果执行的是replaceState({name:"Tom"})

state={
 name:"Tom"
}

react中的事件是合成事件。其中就有事务对事件函数进行封装。

function method(){
    console.log('111')
};
transaction.perform(method);
//执行initialize方法
//输出'111'
//执行close方法

 

**************************************************************************************************************

1.执行dispatchInteractiveEvent,此时isBatchingUpdates的值是false

function dispatchInteractiveEvent(topLevelType, nativeEvent) {
  console.log('dispatchInteractiveEvent',isBatchingUpdates)//dispatchInteractiveEvent false
  interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
}

2._interactiveUpdates函数就是interactiveUpdates$1函数

function interactiveUpdates(fn, a, b) {
  return _interactiveUpdates(fn, a, b);
}

3.此时isBatchingUpdates的值是false,执行performWork(),isBatchingUpdates = true;finally最后执行,将isBatchingUpdates变成false,执行performSyncWork();更新内容。

function interactiveUpdates$1(fn, a, b) {
  console.log('interactiveUpdates$1函数',isBatchingUpdates);//false
  console.log(isBatchingInteractiveUpdates);//false
  if (isBatchingInteractiveUpdates) {
    return fn(a, b);
  }
  // If there are any pending interactive updates, synchronously flush them.
  // This needs to happen before we read any handlers, because the effect of
  // the previous event may influence which handlers are called during
  // this event.
  if (!isBatchingUpdates && !isRendering && lowestPendingInteractiveExpirationTime !== NoWork) {
    // Synchronously flush pending interactive updates.
    performWork(lowestPendingInteractiveExpirationTime, false, null);
    lowestPendingInteractiveExpirationTime = NoWork;
  }
  var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
  var previousIsBatchingUpdates = isBatchingUpdates;
  isBatchingInteractiveUpdates = true;
  isBatchingUpdates = true;
  try {
    return fn(a, b);
  } finally {
    isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
    isBatchingUpdates = previousIsBatchingUpdates;
    if (!isBatchingUpdates && !isRendering) {
      performSyncWork();
    }
  }
}

4.  dispatchEvent()调用batchedUpdates(),isBatching开始是false,执行_batchedUpdates()

var isBatching = false;
function batchedUpdates(fn, bookkeeping) {
  console.log(isBatching);//false
  console.log(isBatchingUpdates);//true
  if (isBatching) {
    // If we are currently inside another batch, we need to wait until it
    // fully completes before restoring state.
    return fn(bookkeeping);
  }
  isBatching = true;
  try {
    return _batchedUpdates(fn, bookkeeping);
  } finally {
    // Here we wait until all updates have propagated, which is important
    // when using controlled components within layers:
    // https://github.com/facebook/react/issues/1698
    // Then we restore state of any controlled component.
    isBatching = false;
    var controlledComponentsHavePendingUpdates = needsStateRestore();
    if (controlledComponentsHavePendingUpdates) {
      // If a controlled event was fired, we may need to restore the state of
      // the DOM node back to the controlled value. This is necessary when React
      // bails out of the update without touching the DOM.
      _flushInteractiveUpdates();
      restoreStateIfNeeded();
    }
  }
}

经过一系列函数调用执行incease()函数,执行setState()函数

Component.prototype.setState = function (partialState, callback) {
  !(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : void 0;
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值