昨天Sixian 提到了 React的新版官方文档,之前一直没有去读,今天抽空读了其中 Escape Hatches
的部分,有一些收获,也有一点感想,在这里简单分享一下。
声明:我经常使用React,但我不是React的专家,我也不再是一个对技术会进行非常深入探究的人了。所以对于React最新的一些API,可能对某些人来说是老生常谈,但对我来说是新鲜的。所以本文只是简单分享一下我看到的之前不知道的一些API.
sixian的Tweet
跑两次的useEffect
开发环境useEffect跑两次是故意的,是为了帮助开发者在开发环境中发现你是否正确地给你的effect做了teardown.
The right question isn’t “how to run an Effect once”, but “how to fix my Effect so that it works after remounting”.
如果你的代码因为useEffect跑两次所以出问题,很可能你用错了useEffect.
Alt text
讨论这样的特性是否是一种傲慢对我来说意义不大,重要的是我理解了其动机。
flushSync API
React有一个flushSync API,可以强制update DOM.在以前我们一般是把希望在DOM更新后才执行的代码放在一个setTimeout里.
Alt text
如果想重置一个Component,直接给它一个新的key
如果希望某个component的props被改变的时候做一些重置,应该直接给这个component赋一个新的key,使React直接重建整个DOM,而不是用useEffect手动做重置工作。
其实以前我也经常这么干,比如Modal在关闭和打开后重置里面Form的值,我会直接给Modal一个新的key.一直不知道这是否是一个best practice,现在得到了官方认证。
Alt text
useSyncExternalStore
这是一个我不知道的Hook,看起来很适合用于把别的库移植到React时使用,而且它对SSR非常友好。
一些感想
很多人觉得React繁琐,心智负担特别大,我也这么认为。但我一直觉得,这不是React本身的问题,而是JavaScript的问题。
React是一个特别函数式编程思维的框架,但很可惜,JavaScript只是一个半吊子的函数式编程语言,它只是在被设计的时候学了一点Lisp的皮毛,也提供了一点点函数式的API,但它没有很多真正的函数式编程语言应该有的基本特性,才导致了我们要写额外的代码来解决一些问题。
例如,Memoization 在一些函数式编程语言里是标配,但JavaScript里没有,所以你需要给函数手动套一层React.useCallback
.
函数式编程语言里, Immutable也是标配,而在JavaScript里,需要用Immer之类的第三方库。
所以这就是为什么在多年前我很看好ReasonML (现在叫 ReScript)这个语言,因为它本身就是真正的函数式编程语言(它是基于OCaml的JavaScript方言),你会发现,用它来写React是多么舒服的一件事,因为语言本身就提供了你在JavaScript里需要调API才能实现的功能。有趣的是,React在刚开始设计的时候用的就是OCaml.
成也JavaScript,败也JavaScript.