你可能正在寻找 useSyncExternalStore

[name|Friend], when you see a useEffect that updates a useState and returns a value, you might be looking for a useSyncExternalStore. This is my current vendetta.

[name|Friend],当你看到一个更新 useState 并返回值的 useEffect 时,你可能在找的是 useSyncExternalStore。这是我现在的执念。

Makes it easier to fix jank like this:

让修复这种卡顿变得更容易:

Flash of no visualization

PS: you can read and share this online

PS:你可以 在线阅读并分享这篇文章

A common pattern

一个常见模式

A pattern I see a lot in our React code combines a state, an effect, and a subscription:

我在我们的 React 代码中经常看到一种模式,它把 state、effect 和订阅组合在一起:

function useSomeValue() {
  const [value, setValue] = useState(0)

  useEffect(() => {
    const eventSource = getEventSource()
    eventSource.subscribe((val) => setValue(val))

    return () => {
      eventSource.unsubscribe()
    }
  }, [])

  return value
}

This is a custom hook that subscribes to an event source like a browser API, or a ResizeObserver, or a state machine. Sometimes includes refs to the DOM to measure things.

这是一个自定义 hook,用于订阅事件源,比如浏览器 API、ResizeObserver 或状态机。有时还会包含对 DOM 的 ref 以进行测量。

This works.

这能行。

The effect runs on mount, subscribes to a thing, updates state to trigger re-renders, and cleans up with an unsubscribe when the component unmounts. It's a pattern you're familiar with after writing React for a while and you easily spot what's happening.

该 effect 在挂载时运行,订阅某个东西,更新 state 以触发重新渲染,并在组件卸载时通过取消订阅进行清理。这是你在写 React 一段时间后熟悉的模式,你很容易就能看出发生了什么。

Can lead to jank with server rendering

在服务端渲染时可能导致卡顿

The problem is that React has to render your component 2+ times before it settles into what you wanted. First it renders with a default value, then the effect runs, then it re-renders when state updates.

问题是 React 必须渲染你的组件 2 次或更多次,才能稳定到你想要的状态。首先用默认值渲染,然后 effect 运行,接着在 state 更新时重新渲染。

What you saw in the gif above is a slow hydration process.

你在上面的 gif 中看到的是一个缓慢的 hydration 过程。

  1. Component rendered on server with default values
  2. 组件在服务器端以默认值渲染
  3. Couldn't subscribe to browser events because there's no browser (I haven't confirmed if effects run at all)
  4. 无法订阅浏览器事件,因为没有浏览器(我还没确认 effect 是否会运行)
  5. HTML showe...
开通本站会员,查看完整译文。

Главная - Вики-сайт
Copyright © 2011-2025 iteam. Current version is 2.146.0. UTC+08:00, 2025-10-03 02:01
浙ICP备14020137号-1 $Гость$