Home ReactJS 源码阅读
Post
Cancel

ReactJS 源码阅读

之前尝试不用编译器插件的前提下实现 compose Remember,想到的方案是牺牲一定的使用自由度,调用顺序获得 remember 能力,今天看了 ReactJS,其实他就是这样实现的。

https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e

react-to-compose

useRef/useMemo 类似 by remember,不会触发变化,但是在此组件实例中的值会被记住,不会因重新渲染而变化。 useState 类似 by remember{ mutableStateOf } 可触发变化

compose 的 api 更好理解些。


由于 JS 是弱类型,ReactJS 有很多隐式的契约,比如:

1
2
3
4
5
6
7
8
9
const [state,setState] = useState(false);

// setState 可传一个函数,其参数为当前状态,返回值为新状态
setState((prevState)=>!prevState);
// 也可传一个值
setState(!state)
// 甚至可以传任意不正确的函数,或任意类型
setState(()=>{}) // 无返回值

1
2
3
4
5
6
7
8
9
10
<li key={item.id} 
    ref={(node)=>{
        // node == null 时代表需要清除,即当前节点要被移除了
        if(node==null) {
            getRefs().delete(item.id);
        } else {
            getRefs().set(item.id, node);
        }
    }}
>item</li>

类型不确定,让 API 学习成本剧增,也极易写出编译正常而实际逻辑并不正确的代码。类型确定的 Kotlin ,则可以使用:

1
2
3
4
5
6
7
8
DisposableEffect {
    // do something

    // DisposableEffect 最后必须是 onDispose ,否则编译不过
    onDispose {
        // do when dispose
    }
}

对应的 js 写法是:

1
2
3
4
5
6
7
8
useEffect(()=>{
    // do something

    // 以下 dispose function 是可选的
    return () => {
        // do when dispose
    }
})

上例中 DisposableEffect 表意明确,而 useEffect 则有更强的自由度,但理解及记忆此 api 的学习成本则更高。

这是 JavaScript 弱类型不得已而为之,在 Kotlin/TypeScript 强类型语言中,不应照抄,避免使用 Any? 类型

Ref 是命令式的,应尽量避免使用。

This post is licensed under CC BY 4.0 by the author.