Skip to main content

使用随机性

在 Remotion 中,以下内容是一种反模式:

tsx
const MyComp: React.FC = () => {
const [randomValues] = useState(() =>
new Array(10).fill(true).map((a, i) => {
return {
x: Math.random(),
y: Math.random(),
};
}),
);
// Do something with coordinates
return <></>;
};
tsx
const MyComp: React.FC = () => {
const [randomValues] = useState(() =>
new Array(10).fill(true).map((a, i) => {
return {
x: Math.random(),
y: Math.random(),
};
}),
);
// Do something with coordinates
return <></>;
};

虽然这在预览时可以工作,但在渲染时会出错。原因是 Remotion 在并行渲染帧时会启动多个网页实例,而随机值在每个实例上都会不同。

修复问题

使用 Remotion 中的 random() API 来获取确定性伪随机值。传入一个种子(数字或字符串),只要种子相同,返回值就会相同。

tsx
import { random } from "remotion";
const MyComp: React.FC = () => {
// No need to use useState
const randomValues = new Array(10).fill(true).map((a, i) => {
return {
x: random(`x-${i}`),
y: random(`y-${i}`),
};
});
 
return <></>;
};
tsx
import { random } from "remotion";
const MyComp: React.FC = () => {
// No need to use useState
const randomValues = new Array(10).fill(true).map((a, i) => {
return {
x: random(`x-${i}`),
y: random(`y-${i}`),
};
});
 
return <></>;
};

现在所有线程上的随机值将会相同。

误报

当使用 Math.random() 时收到 ESLint 警告,但您完全了解上述情况吗?使用 random(null) 来获取真正的随机值而不会收到警告。

例外:在 calculateMetadata() 内部

calculateMetadata() 中使用真正的随机值是安全的,因为它只会被调用一次,而不是并行调用。

另请参阅