为什么 React 在 useState 中使用了错误的值?
Why is React using the wrong value in useState?
我有一个像这样的 React 组件:
https://codepen.io/darajava/pen/NWrdWeP?editors=0010
function TestUseState() {
const [count, setCount] = useState(0);
const buttonRef = useRef(null);
useEffect(() => {
buttonRef.current.addEventListener("click", () => {
alert(count);
});
setCount(10000);
}, []);
return (
<div ref={buttonRef}>
Click
</div>
)
}
我在按钮上设置了一个事件监听器,它似乎取状态的初始值,之后直接设置它。这是预期的行为吗?我怎样才能避免这种情况?
有问题的实际代码(无效,仅添加了相关部分):
const Game = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [player, setPlayer] = useState<IPlayer>();
const setPosition = (newPos) => {
console.log(player); // <--- player is undefined on mousemove
};
useEffect(() => {
canvas = canvasRef.current;
ctx = canvas.getContext('2d');
canvas.addEventListener('mousemove', (e: MouseEvent) => {
setPosition(getCursorPosition(canvas, e));
});
}, []);
return (
<canvas ref={canvasRef} styleName="canvas" />
);
}
是的,这是预料之中的,但我能理解为什么它看起来很奇怪。
当您在 useEffect 挂钩中添加 ref 时,您将关闭 count 的值并将其保存以备后用,因此当您单击 sub 时,它会显示组件初始化时的值。
如果想提醒count的实际值可以在div后面加上onClick={()=>alert(count)}
,这样也比较符合React的声明式
不鼓励您在 React 中使用 refs,因为 React 维护一个虚拟 dom。当您需要直接访问 dom 个元素时,您可以使用 refs。
编辑:您也可以将其用于鼠标移动事件:
https://reactjs.org/docs/events.html#mouse-events
在功能组件的主体中单独编写处理函数,并将其传递给 canvas 元素的 onMouseMove
属性。
我有一个像这样的 React 组件:
https://codepen.io/darajava/pen/NWrdWeP?editors=0010
function TestUseState() {
const [count, setCount] = useState(0);
const buttonRef = useRef(null);
useEffect(() => {
buttonRef.current.addEventListener("click", () => {
alert(count);
});
setCount(10000);
}, []);
return (
<div ref={buttonRef}>
Click
</div>
)
}
我在按钮上设置了一个事件监听器,它似乎取状态的初始值,之后直接设置它。这是预期的行为吗?我怎样才能避免这种情况?
有问题的实际代码(无效,仅添加了相关部分):
const Game = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [player, setPlayer] = useState<IPlayer>();
const setPosition = (newPos) => {
console.log(player); // <--- player is undefined on mousemove
};
useEffect(() => {
canvas = canvasRef.current;
ctx = canvas.getContext('2d');
canvas.addEventListener('mousemove', (e: MouseEvent) => {
setPosition(getCursorPosition(canvas, e));
});
}, []);
return (
<canvas ref={canvasRef} styleName="canvas" />
);
}
是的,这是预料之中的,但我能理解为什么它看起来很奇怪。
当您在 useEffect 挂钩中添加 ref 时,您将关闭 count 的值并将其保存以备后用,因此当您单击 sub 时,它会显示组件初始化时的值。
如果想提醒count的实际值可以在div后面加上onClick={()=>alert(count)}
,这样也比较符合React的声明式
不鼓励您在 React 中使用 refs,因为 React 维护一个虚拟 dom。当您需要直接访问 dom 个元素时,您可以使用 refs。
编辑:您也可以将其用于鼠标移动事件:
https://reactjs.org/docs/events.html#mouse-events
在功能组件的主体中单独编写处理函数,并将其传递给 canvas 元素的 onMouseMove
属性。