指南 · 09

SSR、测试与生产环境

服务端渲染、水合、测试,以及可以依赖的清理规则。

服务端渲染

Hook 的值会把初始值渲染到服务端标记中,水合后动画会继续。React 18 及以上版本用 useId 生成稳定的变量名;在 React 16 和 17 的服务端,请传入 id。

app/layout.jsx
import { AnimatedProvider } from '@kkwaenggwari/animated';

// The package entry is marked 'use client'. A server layout can render the
// provider directly; hooks and Animated.<tag> go inside Client Components.
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <AnimatedProvider>{children}</AnimatedProvider>
      </body>
    </html>
  );
}

旧版 React 中的稳定 id

只有在使用 React 16 或 17 进行服务端渲染时才需要。

ssr.jsx
// React 18+ uses useId automatically. On React 16/17 servers, pass a stable id.
const progress = useAnimatedValue(0, { id: 'hero-progress' });

可以依赖的清理

组件拥有的一切都会随组件一起释放。

  • useAnimated、useAnimatedValue、useTimeline 和 useReorder 会在卸载时停止它们的控制器和监听器。
  • 在 useAnimated 工厂函数中声明的控制器和输入,会在依赖变化时一起被替换。
  • Animated.Keep 在动效结束后移除离开的子元素,新的 pose 会从当前位置打断原动效。
  • 在 React 之外,bind、bindOutput、createTimeline 和 createLayoutScene 都会返回显式的 dispose。

测试

flushAnimatedUpdates() 会同步应用待处理的输出,让确定性测试可以对 DOM 做断言。

Meter.test.jsx
import { flushAnimatedUpdates } from '@kkwaenggwari/animated';

act(() => progress.setValue(0.5));
flushAnimatedUpdates();
// Pending style writes are applied now; assert on the DOM.

文本、属性与对象属性

useAnimated 中的 output(target, mapping) 负责 style、属性、文本或对象属性的输出。bindOutput 会立即挂载同样的映射,并返回 flush 和 dispose。

Counter.jsx
const label = useRef(null);

const count = useAnimated(
  0,
  (value) => {
    output(label, { text: new AnimatedComputed([value], (v) => `${Math.round(v * 100)}%`) });
    timing(value, { toValue: 1, duration: 1200 });
  },
  [],
);

<span ref={label} />;

搜索

输入关键词搜索文档。