React State Variables Mysteriously Changing Before 'beforeunload' Function
UPDATE: I created a minimum reproducible sample here: https://react-wsaei2.stackblitz.io Editor link: https://stackblitz.com/edit/react-wsaei2 In my app I'm using a sendBeacon func
Solution 1:
You need to define success
and loggedOut
(and other used variables) as effect dependencies.
useEffect(() => {
constunlockStory = (e) => {
e.preventDefault();
console.log("Inside unlockStory. success, loggedOut:", success, loggedOut);
if (!success && !loggedOut) {
console.log("Inside if")
navigator.sendBeacon(`/api/stories/`, JSON.stringify({body: {locked: true}}));
}
e.returnValue = "What's going on?";
}
// Add event listener to run code before window closeswindow.addEventListener("beforeunload", unlockStory);
return() => {
window.removeEventListener("beforeunload", unlockStory);
}
}, [success, loggedOut]); // Run on every success or loggedOut change
There is no need to manually remove event listeners as:
React also cleans up effects from the previous render before running the effects next time.
Sometimes is easier to use class based components:
classStartClassextendsReact.Component {
constructor(props) {
super(props);
this.state = {
loggedOut: false,
success: false,
storyObj: {
segCount: 2
}
}
}
componentDidMount() {
this.setState( { loggedOut: true } );
window.addEventListener("beforeunload", this.unlockStory);
return() => {
window.removeEventListener("beforeunload", this.unlockStory);
}
}
handleRefresh = () => {
let {success, loggedOut} = this.stateconsole.log("Handling refresh: success, loggedOut", success, loggedOut);
window.location.reload(true);
}
unlockStory = (e) => {
e.preventDefault();
let {success, loggedOut} = this.stateconsole.log("Inside unlockStory. success, loggedOut:", success, loggedOut);
if (!success && !loggedOut) {
console.log("Inside if")
navigator.sendBeacon(`/api/stories/`, JSON.stringify({body: {locked: true}}));
}
e.returnValue = "What's going on?";
}
render() {
return (
<Containerfluid><Row><Col><p>
To reproduce:<br/> Open console, then click the Refresh page button below. When the alert pops up check the console and you'll see that the loggedOut variable has changed from true to false.
</p><p>
The same behavior occurs when you refresh via the browser, but you can't see the log as the console is cleared upon refresh.
</p>
{this.state.loggedOut && <ButtononClick={this.handleRefresh}>Refresh page</Button>}
</Col></Row></Container>
);
}
}
Post a Comment for "React State Variables Mysteriously Changing Before 'beforeunload' Function"