指南 · 09
SSR、测试与生产环境
服务端渲染、水合、测试,以及可以依赖的清理规则。
服务端渲染
Hook 的值会把初始值渲染到服务端标记中,水合后动画会继续。React 18 及以上版本用 useId 生成稳定的变量名;在 React 16 和 17 的服务端,请传入 id。
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 进行服务端渲染时才需要。
// 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 做断言。
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。
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} />;