从一个PR窥探React未来开发方式

【从一个PR窥探React未来开发方式】大家好,我是卡颂。
都说HooksReact的未来,但Hooks的最佳实践是什么呢?
关于这块知识,官方文档一点儿都没提及。
所以在实际项目中,常会出现类似下面的问题:

// ... useEffect(() => { fetchData(a, b).then( // ... ) }, [a, b]) //...

useEffect依赖了a b两个状态,当其中任意一个变化后会执行fetchData请求数据。
当应用变得复杂,要追踪ab何时变化变得越来越难。
假以时日接口调整,fetchData还需要状态c作为参数。那么追踪状态变化的难度又会进一步提高。
从一个PR窥探React未来开发方式
文章图片

最终会导致:
  • 轻则无意义的fetchData多次调用
  • 重则逻辑出现难以追查的bug
有朋友会说:你可以封装自定义Hook啊。
这只是将问题隐藏的更深了......
从一个PR窥探React未来开发方式
文章图片

如何解决这个问题 以上问题的本质原因是:副作用实在太多,可以被当作副作用的东西也实在太多。这导致useEffect被滥用。
所以,要解决滥用问题,就需要为不同类型副作用提供官方解决方案。
这样,具体问题有了具体解决方案,才不会useEffect一把梭。
从一个PR看到变化 最近React有个很不起眼的PR:
从一个PR窥探React未来开发方式
文章图片

大体意思是:
在之前,当你在一个已经卸载的组件(unmounted)中调用setState会触发一个warning,这个PR将移除这个warning
举个例子,以下代码在组件mount时注册handleChange
useEffect(() => { function handleChange() { setState(store.getState()) } store.subscribe(handleChange)return () => store.unsubscribe(handleChange) }, [])

如果你忘记写这行解绑代码:
return () => store.unsubscribe(handleChange)

那么组件卸载后handleChange也可能被调用,进而调用setState
这是潜在的内存泄漏。
在之前的React中,这种行为会报warning
那为什么要移除这种行为下的warning呢?
从一个PR窥探React未来开发方式
文章图片

PR的背后 一方面,这个warning有一定概率误判,比如点击按钮提交表单:
async function handleSubmit() { setPending(true) await post('/someapi') setPending(false) }

点击按钮后调用setPending触发loading图标显示,接着发起post请求。
有可能请求返回前组件就卸载了,此时会调用:
setPending(false)

并不会有内存泄漏风险,但是会报warning
从一个PR窥探React未来开发方式
文章图片

不过warning移除还有另一个更本质的原因:
在第一个示例中,我们在useEffect中调用store.subscribe,这种行为可以归类为:
在组件中订阅外部源
什么是外部源呢?
任何变化与否不受React控制的源都是外部源。
比如:
  • 各种第三方状态管理库
  • 希望location.hash变化触发组件更新
未来所有这类行为都会收敛到useMutableSource这个Hook中。
从一个PR窥探React未来开发方式
文章图片

更多例子 再比如,对于I/O操作(比如请求数据)这种大家都会放在useEffect中的逻辑,未来使用resource结合Suspense可能是更好的选择:
const resource = fetchDetail(); function Page() { return ( Loading...}>
); }function Details() { const data = https://www.it610.com/article/resource.read(); return {data.name}; }

以上例子中,调用fetchDetail会发起数据请求。
Details组件调用resource.read直接消费数据即可。
如果数据还未返回,视图会渲染最近的Suspensefallback(即Loading...)。
总结 副作用是多种多样的,以前没得选,只能用useEffect
随着React18的稳定,面对不同副作用场景,会有更明确的解决方案。
届时,可能才最终迎来Hooks真香的时代......

    推荐阅读