[英]How to use useState in addEventListener?
If I rightClick the red DivElement, I want to change my state如果我右击红色的 DivElement,我想改变我的状态
As the state has been changed, so I thought I could see console.log由于状态已经改变,所以我想我可以看到console.log
But It does not work但它不起作用
Here is my code这是我的代码
import { useState, useRef, useEffect } from "react";
function Main() {
const [testState, setTestState] = useState(0);
const testRef = useRef(null);
function clickHandler(event) {
setTestState(testState + 1);
}
useEffect(() => {
if (!testRef) return;
testRef.current.addEventListener('contextmenu', (event) => { clickHandler(event) });
}, [testRef]);
useEffect(() => {
console.log('testState: ', testState);
}, [testState]);
return (
<div
ref={testRef}
style={{width: '100%', display: 'block', height: '32px', backgroundColor: 'red'}}
/>
);
}
export default Main;
the problem comes when you are referencing your state, keep in mind that setState is executed asynchronously (think about set state as a request to rerender the component).当您引用您的状态时,问题就出现了,请记住 setState 是异步执行的(将 setState 视为重新渲染组件的请求)。
by changing your setTestState(testState + 1);
通过改变你的setTestState(testState + 1);
setTestState((oldVal) => oldVal + 1);
your example will work.你的例子会起作用。 take a look to this stackblitz example看看这个 stackblitz例子
regards,问候,
You should use a cleanup function
and preventDefault
on clickHandler.您应该在 clickHandler 上使用cleanup function
和preventDefault
。
import { useState, useRef, useEffect, useCallback } from "react";
function Main() {
const [testState, setTestState] = useState(0);
const testRef = useRef(null);
const clickHandler = useCallback((event) => {
event.preventDefault();
setTestState((test) => test + 1);
}, []);
useEffect(() => {
const refElement = testRef.current;
refElement.addEventListener("contextmenu", clickHandler);
return () => refElement.removeEventListener("contextmenu", clickHandler); //cleanup function
}, [clickHandler]);
useEffect(() => {
console.log("testState: ", testState);
}, [testState]);
return (
<div
ref={testRef}
style={{
width: "100%",
display: "block",
height: "32px",
backgroundColor: "red"
}}
/>
);
}
export default Main;
Here is a working code snippet:这是一个工作代码片段:
function Main() {
const [testState, setTestState] = useState(0);
const testRef = useRef(null);
useEffect(() => {
function clickHandler(event) {
setTestState((old) => old + 1);
}
if (!testRef) return;
const ref = testRef.current;
ref.addEventListener("contextmenu", clickHandler);
return () => ref.removeEventListener("contextmenu", clickHandler);
}, [testRef, testState]);
useEffect(() => {
console.log("testState: ", testState);
}, [testState]);
return (
<div
ref={testRef}
style={{
width: "100%",
display: "block",
height: "32px",
backgroundColor: "red",
}}
/>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.