解决Error: Calling setState synchronously within an effect can trigger cascading renders
useEffect(() => {
const currentExtensionIds = new Set(extensions.map((ext) => ext.manifest.id));
const processedIds = processedExtensionsRef.current;
// 激活新的 extensions
extensions.forEach((extension) => {
const extensionId = extension.manifest.id;
if (!processedIds.has(extensionId)) {
extensionManager.activateExtension(extensionId);
processedIds.add(extensionId);
}
});
// 停用不再需要的 extensions
const idsToDeactivate = Array.from(processedIds).filter(
(id) => !currentExtensionIds.has(id),
);
idsToDeactivate.forEach((extensionId) => {
extensionManager.deactivateExtension(extensionId);
processedIds.delete(extensionId);
});
startTransition(() => setInitialized(true));
}, [extensions]);
startTransition 包裹 setInitialized 即可——它把状态更新标记为非紧急的过渡更新,打破同步链路,消除 lint 警告:
startTransition 的作用:将 setInitialized(true) 标记为过渡更新(transition),React 不会立即同步处理它,而是在当前 effect 完成后异步调度,从而避免"effect 内同步 setState 触发级联渲染"的问题。
