gpt4 book ai didi

reactjs - 正在重置的状态

转载 作者:行者123 更新时间:2023-12-03 15:19:06 24 4
gpt4 key购买 nike

React 和 React 钩子(Hook)的新手。我试图理解为什么我的状态被 initialState 覆盖。

当我输入一个值时,事情会按预期工作。但是,当我调整窗口大小时,它会将其重置为 initialState,我不知道为什么。
将值插入输入后updateBox显示正确的值。

任何人都可以为我解释发生了什么吗?

https://stackblitz.com/edit/react-hdf3sg


import React,{useState,useEffect,useRef} from 'react';
import './Layout.scss';

const initLayout = {
size:{
width: 16,
height: 16,
}
}
const clone = (obj) => {
return JSON.parse(JSON.stringify(obj));
}

const Layout = ({props}) => {

const boxContainer = useRef(null);

const [layoutState,setLayoutState] = useState(initLayout)
const [boxStyle,setBoxStyle] = useState({
"height": "100%",
"width": "90%",
})

useEffect(() =>{
// State did update
console.log("useEffect:State did update:",layoutState.size.width,":",layoutState.size.height)
// updateBox()
});

useEffect(() =>{
// Component did mount
console.log("Component did mount")
window.addEventListener("resize", updateBox);
return () => {
window.removeEventListener("resize", updateBox);
};
}, []);

useEffect(() => {
// This state did update
console.log("layoutState did update",layoutState)
updateBox()
}, [layoutState]);

const updateBox = () => {
console.log("updateBox",layoutState.size.width,":",layoutState.size.height)

let percentage = (layoutState.size.height/layoutState.size.width) * 100
if(percentage > 100){
percentage = 100
}
percentage = percentage+"%"

// console.log("percentage",percentage)

const cloneBoxStyle = clone(boxStyle)

cloneBoxStyle.width = "100%"
cloneBoxStyle.height = percentage
setBoxStyle(cloneBoxStyle)

// console.log("boxContainer",boxContainer)
// console.log("height",boxContainer.current.clientHeight)
// console.log("width",boxContainer.current.clientWidth)

}



const sizeRatioOnChange = (widthArg,heightArg) => {
let width = (widthArg === null) ? layoutState.size.width : widthArg;
let height = (heightArg === null) ? layoutState.size.height : heightArg;

const cloneLayoutState = clone(layoutState);
cloneLayoutState.size.width = width
cloneLayoutState.size.height = height

setLayoutState(cloneLayoutState)
}

const render = () => {
console.log("render",layoutState.size.width,":",layoutState.size.height)
// updateBox()
// const enlargeClass = (true) ? " enlarge" : "" ;

return (
<div className={"layout"} >
<div className="layout-tools-top">
Layout Size Ratio
<input
type="number"
value={layoutState.size.width}
onChange={(e) => {sizeRatioOnChange(e.target.value,null)}}/>
by
<input
type="number"
value={layoutState.size.height}
onChange={(e) => {sizeRatioOnChange(null,e.target.value)}}/>

<button className="button close">
Close
</button>
</div>

<div className="layout-container">
<div className="layout-tools-side">
<h2>Header</h2>
<ul>

</ul>
<form>
<input type="text" placeholder="Add Item" />
</form>
</div>
<div className="layout-box-container" ref={boxContainer}>
<div className="layout-box" style={boxStyle}>
{/* {boxStyle.height} x {boxStyle.width} */}
</div>
</div>
</div>
</div>
);
}

return render();
};

export default Layout;

enter image description here

最佳答案

问题在这里:

 useEffect(() => {
// Component did mount
console.log("Component did mount")
window.addEventListener("resize", updateBox); //HERE
return () => {
window.removeEventListener("resize", updateBox);
};
}, []);
更新框 因为 的回调函数,你绑定(bind)到resize window事件的函数将使用它被绑定(bind)时的状态(当组件挂载时)。添加事件监听器 在自己的闭包中执行。
要解决这个问题,您必须将状态保存在 ref 中,这样它仍然是最新的,当您从另一个闭包访问它时也是如此。
所以首先创建 ref 并将状态存储在其中:
const [layoutState,setLayoutState] = useState(initLayout);
const layoutRef= useRef({});
layoutRef.current = layoutState;
然后在 里面更新框 您必须从 读取布局“状态”的功能布局引用 而不是 布局状态 :
  const updateBox = () => {
let percentage = (layoutRef.current.size.height/layoutRef.current.size.width) * 100

if(percentage > 100){
percentage = 100
}
percentage = percentage+"%"

const cloneBoxStyle = clone(boxStyle);

cloneBoxStyle.width = "100%"
cloneBoxStyle.height = percentage
setBoxStyle(cloneBoxStyle)
}
让我知道它是否有效,请提供反馈,因为这是我在这里的第一个答案:)

关于reactjs - 正在重置的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56511176/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com