useEffectEvent (React19.2)

10 小时前(已编辑)
/ ,
3

useEffectEvent (React19.2)

useEffectEvent 允许创建一个函数,这个函数专门用于在effect中调用,函数中引用的props/state不受effect回调函数闭包影响,永远能拿到最新的props/state值。在某些情况下,你可能只想在 Effect 中读取最新的 props 或 state,而不希望当这些值改变时让 Effect 重新运行。要在 Effect 中读取最新的 props 或 state,而不让这些值成为响应式依赖,请把它们放进一个 Effect Event 中。

解决闭包陷阱

闭包陷阱代码

export default function CloserBug() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        const timer = setInterval(() => {
         console.log(count);
        }, 1000);
        return () => clearInterval(timer);
    }, []);

    const handleClick = () => {
        setCount(count + 1);
    };

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
        </div>
    );
}

传统解决方案1

export default function CloserBug() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        const timer = setInterval(() => {
         console.log(count);
        }, 1000);
        return () => clearInterval(timer);
    }, [count]);

    const handleClick = () => {
        setCount(count + 1);
    };

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
        </div>
    );
}

传统解决方案2

export default function CloserBug() {
    const [count, setCount] = useState(0);
    const countRef = useRef(count);
    useEffect(() => {
        const timer = setInterval(() => {
         console.log(count);
        }, 1000);
        return () => clearInterval(timer);
    }, [count]);

    const handleClick = () => {
        setCount(count + 1);
        countRef.current = count;
    };

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
        </div>
    );
}

使用useEventEffect

export default function CloserBug() {
    const [count, setCount] = useState(0);

    const onCount = useEffectEvent(() => {
        console.log(count);
    })

    useEffect(() => {
        const timer = setInterval(() => {
            onCount()
        }, 1000);
        return () => clearInterval(timer);
    }, []);

    const handleClick = () => {
        setCount(count + 1);
    };

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
        </div>
    );
}

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...