I need to find a way to use both a variable declared inside a functional component and part of the props of the functional component inside the callback function on a mousemove eventlistener.
So far I have the code below, but it seems the props don't get updated within the onHover function.
The full component is a bit more complex than this example code, but the example below is the most basic way of showing my problem. On initialisation the value in the props would be 1, and in the onHover function it stays 1 even if there's a change and re-render and elsewhere in the component it shows the correct value of 2.
Is there a way to make sure the onHover function references the most recent version of the props?
I've tried using a useEffect hook to remove and add the eventlistener, but then I can't seem to access the variableNeededInOnHover
function FunctionalComp(props){
let variableNeededInOnHover = null;
useEffect(()=>{
window.addEventListener("mousemove", onHover, true)
return () => {
window.removeEventListener("mousemove", onHover, true)
}
}, [])
function onHover(event) {
console.log(props.value) // stays 1
console.log(variableNeededInOnHover)
}
return ( <div>{props.value}</div> ) // Updates to show a value of 2
}
Is there a way to solve this problem?
EDIT:
I've tried Taxel's proposed solution and it seems that the variableNeededInOnHover keeps it's null value even though I set it's value in the useEffect hook, mimicing the componentDidMount() lifecycle method.
function FunctionalComp(props){
let variableNeededInOnHover = null;
useEffect(()=>{
variableNeededInOnHover = "Non Null Value";
}, [])
useEffect(()=>{
window.addEventListener("mousemove", onHover, true)
return () => {
window.removeEventListener("mousemove", onHover, true)
}
}, [props.value])
function onHover(event) {
console.log(props.value) // stays 1
console.log(variableNeededInOnHover)
}
return ( <div>{props.value}</div> ) // Updates to show a value of 2
}
I'm not 100% sure this solves your issue as you have no way that props.value is being updated in the example. Generally you need to use React state for any values that will get changed and you want to cause a rerender. React wont know about a let that gets updated somewhere.
I've added an example below that shows the value being updated.
function FunctionalComp(props){
const [value, setValue] = React.useState(props.value);
React.useEffect(()=>{
setValue(oldValue => oldValue + 1);
}, [])
React.useEffect(()=>{
window.addEventListener("mousemove", onHover, true)
return () => {
window.removeEventListener("mousemove", onHover, true)
}
}, [value])
function onHover(event) {
console.log(value) // stays 1
}
return ( <div>{value}</div> ) // Updates to show a value of 2
}
ReactDOM.render(
<FunctionalComp value={1} />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>