vaakian / vaakian.github.io

some notes
https://vaakian.github.io
3 stars 0 forks source link

Hooks —— Under The Hood #31

Open vaakian opened 2 years ago

vaakian commented 2 years ago

react hooks 的工作流程初探

闭包(closure

先试着用自己的想法,实现一个useState,通过解构赋值语法,显然应该包含初始值、返回数组,所以有如下:

function useState(initVal) {
    let state = initVal
    const setState = newVal => {
        state = newVal
    }
    return [state, setState]
}

// 
const [count, setCount] = useState(1)
console.log(count) // 1
setCount(2)
console.log(count) // 1

这时候外面的count并不会被改变,因为它仅仅是一个值引用。其次setCount函数被外部引用,所以产生了一个 闭包,内部变量不会被销毁。

如何解决count不变的问题?有一个方法是将count也写成函数,通过函数返回值可以访问到内部的变量。

function useState(initVal) {
    let state = initVal
    const setState = newVal => {
        state = newVal
    }
    return [() => state, setState]
}

const [count, setCount] = useState(1)
console.log(count()) // 1
setCount(2)
console.log(count()) // 2

这里初步实现了需求,但在react中并没有用函数调用方式获得新的值,而是先前直接返回的形式,那么到底是怎么被处理的?

初步肉眼观察/推测流程,hooks内部的值改变,会引起组件刷新(即组件函数重新执行),从而重新调用hooks,然后拿到新的值。

通过查阅相关资料以及技术文档,我的猜想是正确的。下面通过一个简单的实现,初步理解hooks的原理。

const React = function () {
    let _cacheVal = undefined
    let useState = function (initVal) {
        let setState = function (newVal) {
            _cacheVal = newVal
        }
        return [_cacheVal || initVal, setState]
    }
    const render = function (Component) {
        let component = Component()
        component.render()
        return component
    }
    return { useState, render }
}()

function Component() {
    const [count, setCount] = React.useState(1)

    return {
        render: () => {
            console.log(count)
        },
        click: () => {
            setCount(count + 1)
        }
    }
}

let app = React.render(Component) // 1
// 点击,促使_cacheVal变化
app.click()
// 重新执行组件函数,返回新的组件
app = React.render(Component) // 2

//React.render负责重新执行组件函数
//Component.render负责根据状态进行输出结果

// 不会重新调用`Component`
// app.render()

简单来说,就是setState会有两个动作:

其实这里也就解释了为什么setState是异步而不是同步,它会触发render,这种设计与同步任务执行顺序本身就不一致。所以需要使用到useEffect来监听数据变化,关于useEffect原理,后面再进行深入探究。

vaakian commented 2 years ago

这个视频对理解Functional Component有非常大的帮助 How do React hooks really works under the hood

vaakian commented 2 years ago

其它

Function components capture the rendered values.