等待 DOM 元素然后做出反应 - Reactjs

Mic*_*ips 6 javascript reactjs

您好,我有一个类组件,如下所示:

class SomeComponent extends Component {
    componentDidMount = () => {
       const divElement = document.getElementbyId('id'); // this element could take a few seconds to load
       if (props.something1 && props.something2) {
          ..do something with divElement's width
       }
    }
    render() {
      return ....
    }
}
Run Code Online (Sandbox Code Playgroud)

我想等到 divElement 加载完毕,或者在加载 divElement 时触发一个事件,这样我就可以稍后进行计算,尝试添加 setTimeout 但这不起作用

T.J*_*der 15

给你两个答案:

使用 ref (如果您的组件渲染该元素)

如果该元素是由您的组件呈现的,请使用ref

使用 a MutationObserver(如果元素在 React 之外)

如果该元素完全位于页面的 React 部分之外,我会按原样查找它getElementById,如果找不到它,请使用 aMutationObserver等待它被添加。不要忘记删除 中的突变观察者componentWillUnmount

那看起来像这样:

componentDidMount = () => {
   const divElement = document.getElementbyId('id');
   if (divElement) {
      this.doStuffWith(divElement);
   } else {
      this.observer = new MutationObserver(() => {
         const divElement = document.getElementbyId('id');
         if (divElement) {
            this.removeObserver();
            this.doStuffWith(divElement);
         }
      });
      this.observer.observe(document, {subtree: true, childList: true});
   }
}
componentWillUnmount = () => {
    this.removeObserver();
}
removeObserver = () => {
    if (this.observer) {
        this.observer.disconnect();
        this.observer = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

(您可能需要对其进行调整,它是即兴的;MutationObserver有关详细信息,请参阅文档。)


Hao*_* Wu 11

这是一个愚蠢的解决方案,但它完成了它的工作:

const getElementByIdAsync = id => new Promise(resolve => {
  const getElement = () => {
    const element = document.getElementById(id);
    if(element) {
      resolve(element);
    } else {
      requestAnimationFrame(getElement);
    }
  };
  getElement();
});
Run Code Online (Sandbox Code Playgroud)

使用方法:

componentDidMount = async () => {
  const divElement = await getElementByIdAsync('id');
  if (props.something1 && props.something2) {
    // ..do something with divElement's width
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 非常明显的性能和线程阻塞......@Onat (2认同)

Ade*_*ran -1

你可以做类似的事情;

componentDidMount() {
  // Triggering load of some element
  document.querySelector("#id").onload = function() {
    // Write your code logic here
    // code here ..
  }
}
Run Code Online (Sandbox Code Playgroud)

参考https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload

  • 如果 OP 的 `getElementById('id')` 调用不存在该元素,那么您的 `querySelector("#id")` 也不会存在该元素,因此 `querySelector` 将返回 `null` 和您的代码会抛出错误。 (2认同)