我以为useEffect的第一个函数在第一个渲染之前被调用,但是当我调用下面的方法时,恰好在return方法调用被调用之前,我的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;
使用创建的效果在useEffect渲染提交阶段之后运行,因此在渲染周期之后运行。这是为了确保在渲染提交阶段不会执行任何可能导致不一致的副作用。
useEffect
根据文档
不允许在功能组件的主体内部进行突变,订阅,计时器,日志记录和其他副作用(称为React的渲染阶段)。这样做会导致UI中的错误和不一致。 传递到的函数useEffect将在将渲染提交到屏幕后运行。
不允许在功能组件的主体内部进行突变,订阅,计时器,日志记录和其他副作用(称为React的渲染阶段)。这样做会导致UI中的错误和不一致。
传递到的函数useEffect将在将渲染提交到屏幕后运行。
useEffect挂钩可用于复制类组件的,和生命周期方法的行为componentDidMount,具体取决于传递给依赖项数组的参数(这是useEffect的第二个参数)以及在执行下一个效果之前或之前在回调中执行的返回函数卸下componentDidUpdate``componentWillUnmount
componentDidMount
componentDidUpdate``componentWillUnmount
对于某些用途,animations您可以利用useLayoutEffect所有DOM突变后同步执行的情况。使用它从DOM读取布局并同步重新渲染。在浏览器有机会绘制之前,在useLayoutEffect内部计划的更新将被同步刷新。
animations
useLayoutEffect