用react ref更新iframe在firefox和chrome中的行为不一样

下面react组件

import React from "react";

const App = (props) => {
  const iframe = React.useRef();

  React.useEffect(() => {
    (async () => {
      // await new Promise((r) => setTimeout(r, 1));
      iframe.current.contentDocument.body.style.backgroundColor = "salmon";
    })();
  }, []);

  return (
    <>
      <iframe ref={iframe} title="foo" />
    </>
  );
};

export default App;

在chrome里iframe有颜色,但是Firefox里就没有。

如果把 await new Promise((r) => setTimeout(r, 1000)); 这行注释拿掉,也就是加一点sleep, Firefox也有颜色了。为什么?

分别在chrome和Firefox里打开 https://codesandbox.io/s/determined-pike-jc5h3?file=/src/App.js 就能看到现象了。

 

如果在本地PC上执行,在Firefox下,刷新页面是会感觉到有一瞬间iframe有颜色,然后颜色消失了。

参考GPT和自己的思路:

这个问题可能与浏览器的渲染引擎有关。在 Chrome 中,可能会在 useEffect 中的同步代码执行完之前先绘制出 iframe,因此能够正常显示背景颜色。然而,在 Firefox 中,可能会在同步代码执行之前绘制出 iframe,所以无法正常显示背景颜色。

解决方案可以是使用 setTimeout,或者使用 requestAnimationFrame 等异步机制来让代码执行时机更加可控。另外,也可以尝试在 useEffect 中使用 MutationObserver 监听 iframe 的加载情况,确保在适当的时候操作 iframe 的 DOM 元素。