If I rightClick the red DivElement, I want to change my state
As the state has been changed, so I thought I could see 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;
CodePudding user response:
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).
by changing your setTestState(testState 1);
setTestState((oldVal) => oldVal 1);
your example will work. take a look to this stackblitz example
regards,
CodePudding user response:
You should use a cleanup function
and preventDefault
on clickHandler.
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;
Working Codesandbox
CodePudding user response:
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",
}}
/>
);
}