为什么初始状态在反应的"useState"钩子中一遍又一遍地设置

Why is initial state being set over and over again in the "useState" hook of react

我创建了一个监听调整大小事件的函数,它检查 window 宽度并更新我的 IsMobile 变量 if(width<=600 and IsMobile = false) 然后将其设置为 true,反之亦然相反。

代码如下:

import React, { useEffect, useState } from 'react';

export interface MechnicalLiftProps {
}

const MechnicalLift: React.SFC<MechnicalLiftProps> = () => {

    const [IsMobile, setIsMobile] = useState(true)

    const handleWindowChange = () => {

        console.log('window inner width', window.innerWidth);
        console.log('is mobile in handle', IsMobile);

        if (window.innerWidth <= 600 && IsMobile === false) {
            setIsMobile(true);
            console.log('is mobile set to true');
        }

        if (window.innerWidth > 600 && IsMobile === true) {
            setIsMobile(false);
            console.log('is mobile set to false');
        }

    }

    useEffect(() => {
        console.log('mount running');
        window.addEventListener('resize', handleWindowChange)
        handleWindowChange()
        return () => {
            window.removeEventListener('resize', handleWindowChange)
        }
    }, [])

    useEffect(() => {
        console.log('is this mobile ', IsMobile);
    }, [IsMobile])

    return (
        <div>

        </div>
    );
}

export default MechnicalLift;

我的控制台输出:

我觉得每次重新渲染组件时都会设置初始状态,否则为什么 IsMobile 每次在句柄 window 更改时都设置为 true,即使它多次设置为 false。钩子的新手请尽可能详细地解释你的解释

由于 useEffect 上的空数组,您在第一次渲染时只设置了一次事件侦听器。您创建的函数从第一个渲染中引用了 IsMobile,它的值为 true。它的价值永远不会改变。

如果你需要知道状态的最新值,你可以使用设置状态的回调版本:

const handleWindowChange = () => {
  setIsMobile(prev => {
    console.log('previous value', prev);
    if (window.innerWidth <= 600 && prev === false) {
      return true;
    }
    if (window.innerWidth > 600 && prev === true) {
      return false;
    }
    return prev;
  });
});

顺便说一句,如果值未更改,设置状态将不会重新呈现,因此您无需防止将其设置为已有值。换句话说,如果您不需要日志记录,那么您的代码可以简化为:

const handleWindowChange = () => {
  setIsMobile(window.innerWidth <= 600);
}