Происходит ли рендеринг до вызова функции useEffect в React Hooks?

Я бы подумал, что первая функция useEffect вызывается до первого рендеринга, но когда я вызываю метод ниже, мой console.info непосредственно перед вызовом метода возврата, тогда вызывается функция первого параметра 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.info('useEffect before setInView')
        setInView(isInView());
        console.info('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.info('just before render return')
    return (
        <img
            ref = {imageRef}
            src = {inView ? secondaryImg : primaryImg}
            alt = "image here"
        />
    );
};

export default ImageToggleOnMouseOver;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
26
0
36 417
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

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

Ответ принят как подходящий

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

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

Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI.

The function passed to useEffect will run after the render is committed to the screen.

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

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

Спасибо @Shubham, как вы сказали, за «некоторые случаи». Мой случай не из их числа.

Peter Kellner 30.03.2019 15:25

Другие вопросы по теме