Происходит ли рендеринг до вызова функции в React Hooks useEffect? - PullRequest
0 голосов
/ 29 марта 2019

Я бы подумал, что первая функция useEffect вызывается перед первым рендерингом, но когда я вызываю метод ниже, мой console.log перед вызовом метода return вызывается, тогда вызывается функция первого параметра 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;

Ответы [ 2 ]

3 голосов
/ 30 марта 2019

Эффекты, созданные с помощью useEffect, запускаются после фазы рендеринга и, следовательно, после цикла рендеринга.Это сделано для того, чтобы убедиться, что во время фазы рендеринга не выполняется никаких побочных эффектов, которые могут вызвать несоответствие

Согласно документации

Мутации, подписки, таймеры, ведение журнала и другиепобочные эффекты не допускаются внутри основного тела компонента функции (называемого фазой рендеринга React).Это приведет к запутанным ошибкам и несоответствиям в пользовательском интерфейсе.

Функция, переданная в useEffect, запустится после фиксации рендера на экране.

useEffect hookможет использоваться для репликации поведения методов жизненного цикла componentDidMount, componentDidUpdate и componentWillUnmount для компонентов класса в зависимости от аргументов, передаваемых в массив зависимостей, который является вторым аргументом для useEffect и функции возврата из выполняемого обратного вызоваперед запуском следующего эффекта или перед размонтированием

Для некоторых случаев использования, таких как animations, вы можете использовать useLayoutEffect, который выполняется синхронно после всех мутаций DOM.Используйте это для чтения макета из DOM и синхронного повторного рендеринга.Обновления, запланированные внутри useLayoutEffect, будут сбрасываться синхронно до того, как браузер сможет рисовать.

1 голос
/ 29 марта 2019

Согласно документации useEffect :

Если вы знакомы с методами жизненного цикла класса React, вы можете подумать об использовании Effect Hook как комбинация componentDidMount, componentDidUpdate и componentWillUnmount.

Так что да, он запускается после первого рендера и каждого последующего рендера.

...