React 19的重大更新

12 阅读1分钟

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>
})