React中的Fiber更新机制如何执行的setState

一、认识链表

概率:链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

1、实现一个单链表

/** 链表节点类*/
class Node{
    constructor(val){
        this.val = val		//节点所存值
        this.next = null    //指针,指向下一个节点
    }
}
/** 链表类*/
class LinkList{
    constructor(){
        this.head = null    //链表头
        this.length = 0		//链表长度
    }
	/** 新增节点并加入链表*/
    add(val){
        let node = new Node(val)   
        if(this.head == null){      //若表头为空,则将节点放入表头
            this.head = node
            this.length++
        }else{
            let current = this.head
            while(current.next){      //循环,直到链表的指针为空
                current = current.next
            }
            current.next = node
            this.length++
        }

    }
}


let list1 = new LinkList()

list1.add(1)
list1.add(2)
list1.add(3)
list1.add(4)
console.log(list1)

2、输出结果如下:链表结果
在这里插入图片描述

二、setState 状态更新机制

疑问:
1、setState是同步还是异步?
2、setState为何可以传对象又可以传一个函数?

接下来解决这些疑问:

函数setState调用关系主要分为以下两个部分:
1、将要更新的状态添加到更新队列中;
2、产生一个调度任务。调度任务会遍历更新队列并计算出最终要更新的状态,将其更新到组件实例中,然后完成组件渲染操作。

1、将要更新的状态添加到更新队列中,看看代码的实现

class Queue{
    constructor(payload){
        this.payload = payload
        this.nextNode = null
    }
}


class ListQueue{
    constructor(){
        this.firstNode = null   //链表头
        this.lastNode =null		//链表尾
        this.initState = {}		//初始值
    }
	//	将每一个setState任务加入链表队列中
    enqueue(queue){
        if(this.firstNode ==null){
            this.firstNode = this.lastNode =queue
        }else{
            this.lastNode.nextNode = queue
            this.lastNode = queue
        }
    }
}

let listQueue =new ListQueue()


listQueue.enqueue(new Queue({num:1}))
listQueue.enqueue(new Queue({num:2}))
listQueue.enqueue(new Queue((state)=>{state.num++}))
listQueue.enqueue(new Queue({id:5}))

2、调度任务遍历更新队列

class ListQueue{
    constructor(){
        this.firstNode = null
        this.lastNode =null
        this.initState = {}
    }

    enqueue(queue){
        if(this.firstNode ==null){
            this.firstNode = this.lastNode =queue
        }else{
            this.lastNode.nextNode = queue
            this.lastNode = queue
        }
    }
	
	//调度更新方法
    forceUpdate(){
        let current = this.firstNode
        let currentState = this.initState
        while(current){   //依次取出每一个节点值  更新
            let updateState = typeof current.payload =='function'?current.payload(currentState):current.payload   //判断对象还是函数
            currentState ={...currentState,...updateState
            }    //覆盖原来值
            current = current.nextNode
        }
        return currentState
    }
}

3、最后执行一下listQueue.forceUpdate()就可以将state中的值改变了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

名字还没想好☜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值