【问题标题】:Does a render happen before function in React Hooks useEffect is called?在调用 React Hooks useEffect 中的函数之前渲染是否发生?
【发布时间】:2019-08-20 19:21:13
【问题描述】:

我原以为 useEffect 的第一个函数在第一次渲染之前被调用,但是当我调用下面的方法时,我的 console.log 就在返回方法调用之前被调用,然后 useEffect 的第一个参数函数被调用。

调用顺序:

just before render return
ImageToggleOnScroll.js:8 useEffect before setInView
ImageToggleOnScroll.js:10 useEffect after setInView

来源:

import React, {useState,useRef,useEffect} from "react";

// primaryImg is black and white, secondaryImg is color
const ImageToggleOnMouseOver = ({ primaryImg, secondaryImg }) => {
    const imageRef = useRef(null);

    useEffect(() => {
        console.log('useEffect before setInView')
        setInView(isInView());
        console.log('useEffect after setInView')
        window.addEventListener("scroll", scrollHandler);

        return () => {
            window.removeEventListener("scroll", scrollHandler);
        };
    }, []);

    const isInView = () => {
        if (imageRef.current) {
            const rect = imageRef.current.getBoundingClientRect();
            return rect.top >= 0 && rect.bottom <= window.innerHeight;
        }
        return false;
    };

    const [inView, setInView] = useState(false);
    const scrollHandler = () => {
        setInView(() => {
            return isInView();
        });
    };

    console.log('just before render return')
    return (
        <img
            ref={imageRef}
            src={inView ? secondaryImg : primaryImg}
            alt="image here"
        />
    );
};

export default ImageToggleOnMouseOver;

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    使用useEffect 创建的效果在渲染提交阶段之后运行,因此在渲染周期之后运行。这是为了确保在渲染提交阶段不会执行任何可能导致不一致的副作用

    根据文档

    突变、订阅、计时器、日志记录和其他副作用是 不允许在功能组件的主体内部(指 作为 React 的渲染阶段)。这样做会导致令人困惑的错误和 用户界面不一致。

    传递给useEffect的函数将运行 在渲染提交到屏幕之后。

    useEffect 钩子可用于复制类组件的componentDidMountcomponentDidUpdatecomponentWillUnmount 生命周期方法的行为,具体取决于传递给依赖数组的参数,这是 useEffect 的第二个参数和返回函数在下一个效果运行之前或卸载之前执行的回调中

    对于某些用例,例如animations,您可以使用useLayoutEffect,它在所有DOM 突变后同步执行。使用它从 DOM 读取布局并同步重新渲染。在 useLayoutEffect 中安排的更新将在浏览器有机会绘制之前同步刷新。

    【讨论】:

    • 感谢@Shubham,正如您所说,“某些情况”。我的情况不是其中之一。
    【解决方案2】:

    根据useEffectdocumentation

    如果您熟悉 React 类生命周期方法,可以将 useEffect Hook 视为 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。

    所以是的,它在第一次渲染和每个后续渲染之后运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-29
      • 2020-12-21
      • 2021-01-04
      • 1970-01-01
      • 2021-04-17
      • 2021-03-05
      • 2021-09-14
      • 2021-11-21
      相关资源
      最近更新 更多