React 的 useEffect
,大家都熟吧?这玩意儿就像个万金油,啥副作用都能往里塞:取数据、搞订阅、手动操作 DOM……反正渲染完了,它帮你擦屁股。它帮你擦屁股。
但是!React 团队最近搞了个大新闻,他们居然要对 useEffect
动刀子了!而且,这次的改动,用他们的话说,简直是——“违背祖训”!“违背祖训”!
useEffect
要变身?实验性 CRUD 支持来了!
新的 useEffect
签名,整合了以前一个实验性的 Hook useResourceEffect
的功能,现在长这样:
function useEffect(
create: (() => (() => void) | void) | (() => {...} | void | null),
createDeps: Array<mixed> | void | null,
update?: ((resource: {...} | void | null) => void) | void,
updateDeps?: Array<mixed> | void | null,
destroy?: ((resource: {...} | void | null) => void) | void,
): void
是不是看得一脸懵逼?别慌,我来给你翻译翻译。
以前的 useEffect
,创建和清理都挤在一个函数里,跟两口子似的,难舍难分。举个栗子:
useEffect(() => {
// 创建阶段:发起请求
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(response => response.json())
.then(data => setData(data));
// 清理阶段:取消请求
return () => {
controller.abort();
};
}, [someDependency]);
看到了吧?创建(发起请求)和清理(取消请求)都得写在一个函数里。
现在好了,React 团队直接把它们拆散了!新签名里,创建、更新、销毁,各司其职,清清楚楚:
create
: 专门用来造东西(比如,发个请求,整个订阅)。createDeps
:create
的跟屁虫,它们一变,create
就得重新执行。update
(可选): 想更新?找它!它会拿着create
造出来的东西,给你更新。updateDeps
(可选):update
的小弟,它们一变,update
就得带着老东西,重新来过。destroy
: 可选的销毁时候的回调。
“祖宗之法不可变”?React:我就变!
自从 Hook 在 2016 年推出,到现在已经九年了!九年啊!“组合优于继承”、“函数式编程”,这些 React 的“祖训”,各路大神、大V,哪个没给你讲过几百遍?哪个没给你讲过几百遍?
useEffect
把创建和清理揉在一起,也算是“组合”的一种体现,深入人心。可现在呢?React 团队居然亲手把它拆了!这……这简直是自己打自己的脸啊!
不过,话说回来,这种拆分,对于那些复杂的副作用,确实更清晰、更好管理。以前,你可能得在一个 useEffect
里写一堆 if...else
,现在,你可以把它们放到不同的阶段,代码更清爽,逻辑更分明。
注意!前方高能预警!
这个 CRUD 功能,现在还是个“试验品”,React 团队还没打算把它放出来。你要是头铁,非要试试,记得先去把 feature flag 打开。不然,你会看到这个:
useEffect CRUD overload is not enabled in this build of React.
重要的事情说三遍:这都是猜的!猜的!猜的!猜的!猜的!猜的!
现在,关于这个新特性,React 团队还没放出任何官方文档或者 RFC。所以,这篇文章,你看看就好,别太当真。它就是基于代码瞎猜的。等官方消息出来了,咱们再好好研究!