在 react.js 中加载 DOM 时的回调

IT技术 reactjs
2021-04-06 06:04:41

当我的 react.js 组件的 DOM 元素(包括所有子节点)实际加载到页面上并准备就绪时,我想在我的 react.js 组件上调用回调。具体来说,我有两个组件要渲染相同的大小,选择具有较大自然大小的组件中的最大值。

看起来componentDidMount并不是我真正想要的,因为每个组件只调用一次,但我希望在组件完成渲染时再次调用我的回调。我以为我可以onLoad向顶级 DOM 元素添加一个事件,但我想这仅适用于某些元素,例如<body><img>

6个回答

在 componentDidMount 中添加 onload 侦听器

class Comp1 extends React.Component {
 constructor(props) {
    super(props);
    this.handleLoad = this.handleLoad.bind(this);
 }

 componentDidMount() {
    window.addEventListener('load', this.handleLoad);
 }

 componentWillUnmount() { 
   window.removeEventListener('load', this.handleLoad)  
 }

 handleLoad() {
  $("myclass") //  $ is available here
 }
}
还记得添加删除事件侦听器 componentWillUnmount() { window.removeEventListener('load', this.handleLoad) }
2021-06-09 06:04:41

看起来像componentDidMountcomponentDidUpdate将完成工作的组合第一个在初始渲染后调用,当 DOM 可用时,第二个在任何后续渲染后调用,一旦更新的 DOM 可用。就我而言,我都让它们委托给一个共同的函数来做同样的事情。

但是 componentDidUpdate 会被多次调用,这是不可行的
2021-06-01 06:04:41
当我使用这种方法时,它给了我最大深度,因为它创建了一个无限循环
2021-06-04 06:04:41
@John 以何种方式不可行?
2021-06-09 06:04:41
这只适用于顶级组件吗?这种方法如何确保所有子组件都已完成渲染?
2021-06-13 06:04:41
@brianmearns 在使用像 redux 这样的状态管理库时,父 props 可以更改多次,并且每次 componentDidUpdate 都会被调用。如果我们只需要等待初始 DOM 渲染,在这种情况下将不可行。在这种情况下,在 componentDidMount 中附加负载侦听器似乎更好,如以下答案之一所示。
2021-06-19 06:04:41

的组合componentDidMount,并componentDidUpdate会得到与类组件的代码完成任务。但是,如果您在全功能组件中编写代码the Effect Hook会做得很好,它与componentDidMount相同componentDidUpdate

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

https://reactjs.org/docs/hooks-effect.html

我喜欢这个答案的方向,但是你的例子并没有解决问题。
2021-05-23 06:04:41
我认为这个问题与加载事件有关。使用 useEffect 钩子,您可以检测用户访问“视图/页面/....”的那一刻,您无需等待所有元素都出现在屏幕中
2021-05-28 06:04:41

我将 componentDidUpdate 应用于表以使所有列的高度相同。它的工作原理与 jquery 中的 $(window).load() 相同。

例如:

componentDidUpdate: function() {
        $(".tbl-tr").height($(".tbl-tr ").height());
    }
不幸的是,componentDidUpdate在初始渲染时不会调用,因此在 props 或 state更改之前不会应用您的函数reactjs.org/docs/react-component.html#componentdidupdate
2021-06-03 06:04:41
你为什么在反应中使用 jquery?作者要求提供 React 解决方案,因此无需引入新的额外依赖项,而这些依赖项实际上根本没有用
2021-06-10 06:04:41

我发现,简单地将代码包装在componentDidMount或 中componentDidUpdatesetTimeout时间为 0 毫秒,可确保浏览器 DOM 在执行setTimeout函数之前已使用 React 更改进行更新

像这样:

componentDidMount() {
    setTimeout(() => {
        $("myclass") //  $ is available here
    }, 0)
}

这会将匿名函数放在 JS 事件队列上,以便在当前运行的 React 堆栈帧完成后立即运行。

我对延迟加载图像也使用了相同的技术。如果我直接在 componentDidMount 中调用我的 lazyLoadImages 函数,位于浏览器选项卡中的页面加载指示器将保持旋转,直到所有图像都加载完毕。但是如果把lazyLoadImages 函数用100ms 参数包装在setTimeout 中,这种情况就不同了。当图像开始在后台加载时,加载指示器将很快停止旋转。setTimeout 使体验更好。将延迟加载函数绑定到窗口 onload 事件也是如此,但它不适用于 SPA。
2021-06-01 06:04:41
setTimeout 的意义何在?我理解它在事件队列方面的作用,但你为什么认为这是必要的?根据 react 文档,在加载/更新 DOM 元素之前,不会调用这些方法中的任何一个。通过添加 setTimeout,您将在后续更新中引入竞争条件。
2021-06-16 06:04:41