React 19的重大更新
1. - React Compiler 发布 1.0 稳定版, 告别手动 Memo
在 React 的世界里,性能优化一直是个让人头疼的问题。每次组件的 state 或 props 发生变化,React 都会从根节点开始对比,判断哪些节点需要更新。这种机制导致了大量不必要的重新渲染。
只需要 开启 React Compiler 无需修改任何业务代码,编译器会自动处理所有的性能优化。
没有 React 19.2 以前,需要自己解决 KeepAlive 问题
过去实现组件状态保持(KeepAlive)是个老大难问题
很多人可以认为 display: none 能解决一切,那只能说明的开发经验太浅了
display: none 的局限:
- 组件仍会渲染和初始化
- 获取不到正确的 DOM 尺寸
- 会触发生命周期和副作用
- 多个隐藏组件会造成性能浪费
以前我是自己封装 KeepAlive 组件,需要借助 Suspense 挂起渲染,或手动管理组件卸载,代码复杂且容易出问题,代码大致思路如下
import type { KeepAliveProps } from './type'
import { memo, Suspense, use } from 'react'
import { KeepAliveContext } from './context'
const Wrapper = memo<KeepAliveProps>(({ children, active }) => {
const resolveRef = useRef<Function | null>(null)
if (active) {
resolveRef.current?.()
resolveRef.current = null
}
else {
throw new Promise((resolve) => {
resolveRef.current = resolve
})
}
return children
})
/**
* 利用 Suspense 实现的 KeepAlive 组件
* 当 active 为 false 时,抛异常,触发 Suspense 的 fallback
* 当 active 为 true 时,resolve 异常,触发 Suspense 的正常渲染
*/
export const KeepAlive = memo(({
uniqueKey: key,
active,
children,
}: KeepAliveProps & { uniqueKey?: keyof any }) => {
const { findEffect } = use(KeepAliveContext)
/**
* 触发钩子
*/
useEffect(() => {
const { activeEffect, deactiveEffect } = findEffect(key)
if (active) {
activeEffect.forEach(fn => fn())
}
else {
deactiveEffect.forEach(fn => fn())
}
}, [active, findEffect, key])
return <Suspense fallback={ null }>
<Wrapper active={ active }>
{ children }
</Wrapper>
</Suspense>
})