为什么初始状态在反应的"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);
}
我创建了一个监听调整大小事件的函数,它检查 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);
}