构建牢不可破的 React 组件

I skate to where the puck is going to be, not where it has been.
— Wayne Gretzky

我滑向冰球将要去的地方,而不是它曾经在的地方。
— Wayne Gretzky

Most components are built for the happy path. They work—until they don’t. The real world is hostile. Server rendering. Hydration. Multiple instances. Concurrent rendering. Async children. Portals... Your component could face all of them. The question is whether it survives.

大多数组件都是为快乐路径构建的。它们能工作——直到不能。现实世界是充满敌意的。服务器渲染。水合。多个实例。并发渲染。异步子组件。Portals... 你的组件可能会面对所有这些。问题是它是否能存活。

The real test isn’t whether your component works on your current page. It’s whether it works when someone else uses it—in conditions you didn’t plan for. That’s when fragile components break.

真正的测试不是你的组件在当前页面是否工作。而是当别人在你未预料的条件下使用它时,是否还能工作。那时脆弱的组件就会崩溃。

Here’s how to make it survive.

以下是如何让它存活

#Make It Server-Proof

#让它 Server-Proof

A simple theme provider that reads the user’s preference from localStorage:

一个简单的从 localStorage 读取用户偏好的主题提供器:

function ThemeProvider({ children }) {
 const [theme, setTheme] = useState(
 localStorage.getItem('theme') || 'light'
 )

 return <div className={theme}>{children}</div>
}

Sidenote: Crashes in SSR—reads theme from localStorage

旁注:SSR 中崩溃——从 localStorage 读取主题

But localStorage doesn’t exist on the server. In Next.js, Remix, or any SSR framework, this crashes the build. Move browser APIs into useEffect:

但是 localStorage 在服务器上不存在。在 Next.js、Remix 或任何 SSR 框架中,这会导致构建崩溃。将浏览器 API 移动到 useEffect 中:

function ThemeProvider({ children }) {
 const [theme, setTheme] = useState('light')

 useEffect(() => {
 setTheme(localStorage.getItem('theme') || 'light')
 }, [])

 return <div className={theme}>{children}</div>
}

Sidenote: useEffect defers localStorage to client-side only

注记:useEffect 将 localStorage 延迟到仅客户端侧

Now it renders on the server without crashing.

现在它在服务器上渲染而不会崩溃。

#Make It Hydration-Proof

#让它防水合

I also call this waterproof. The server-safe version works, but users see a flash. Server renders light, client hydrates, then the effect runs and switches to dark:

我也称此为防水。服务器安全版本有效,但用户会看到闪烁。服务器渲染 light,客户端水合,然后效...

开通本站会员,查看完整译文。

Home - Wiki
Copyright © 2011-2026 iteam. Current version is 2.153.0. UTC+08:00, 2026-02-15 20:23
浙ICP备14020137号-1 $Map of visitor$