Skip to content

Instantly share code, notes, and snippets.

@JacobThaDev
Last active March 16, 2024 15:12
Show Gist options
  • Save JacobThaDev/05cb313e9d9d4a5f13c58443159647ed to your computer and use it in GitHub Desktop.
Save JacobThaDev/05cb313e9d9d4a5f13c58443159647ed to your computer and use it in GitHub Desktop.
NextJS maintain state across scopes
const [ account, setAccount ] = useState<AccountData>();
const [ startUpdater, setStartUpdater ] = useState<boolean>(false);
const [ activeTimer, setActiveTimer ] = useState<any>(null);
// export this in your context to make a refresh button also. just call it.
// hence the 5 second throttle. lol. could possibly do some refining here on an edge case
// of where the auto-refresh comes close to the manual refesh.
const update = () => {
// can not be within 5 seconds of each other.
if (account.getLastUpdate() - new Date().getTime() < 5000) {
return;
}
// update account then reset the state so it updates!
// guaranteeeeees we stay in the same scope during this interval!
account.update().then((returnedScope: any) => {
let currentTime = new Date().getTime();
setAccount(returnedScope); // update account data!
});
}
useEffect(() => {
if (startUpdater) {
return; // no need to start again if mounted.
}
// create a new account
const accountScope = new AccountData();
update()
setAccount(accountScope);
}, []);
// starts when `startUpdater` is toggeled to true above for the first time.
// ensures timer only starts once
useEffect(() => {
if (activeTimer) {
clearInterval(activeTimer);
setActiveTimer(null);
}
let newTimer = setInterval(() => {
update();
}, updateDelay);
setActiveTimer(newTimer);
return () => {
if (activeTimer) { // this is mostly to solve a dev mount issue. lol.
clearInterval(activeTimer);
setActiveTimer(null);
}
}
}, [startUpdater]);
/**
* using a class for this to ensure I can stay in the same scope.
* let scope = this;
* setTimeout(() => scope.doSomething());
* const { accountData } = someContext();
*/
class AccountData {
private accountData;
private updateState;
/**
* update all variables and return self.
* @returns this scrope
*/
public async update() {
this.updateState = "updating";
try {
// get your api response here and set this.accountData
this.lastUpdate = new Date().getTime();
this.updateState = "idle";
} catch (err) {
console.log(err);
this.updateState = "error";
}
console.log(response);
return this;
}
public getAccountData() {
return this.accountData;
}
public setAccountData(data:any) {
this.accountData = data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment