Skip to content

Instantly share code, notes, and snippets.

@C5H8NNaO4
Last active February 12, 2022 05:05
Show Gist options
  • Save C5H8NNaO4/4b229eadddfd626c1434f461a7c5b55d to your computer and use it in GitHub Desktop.
Save C5H8NNaO4/4b229eadddfd626c1434f461a7c5b55d to your computer and use it in GitHub Desktop.
How to maintain a reference to the correct scope when calling useState?
//I have the following scenario which I'm not quite sure how to solve.
//This function needs to point to the right scope.
const useState = (...args) => Lifecycle.useState(...args);
//Imagine something like an async react component. It can use a hook useState to obtain a state.
const Foo = async (props) => {
console.log ("Rendering Foo")
const [state] = await useState();
const [state2] = await useState();
return {'foo':[state,state2]};
}
//Another component that uses the same hook
const Bar = async (props) => {
console.log ("Rendering Bar")
const [state] = await useState();
const [state2] = await useState();
return {'bar':[state,state2]};
}
//Simulate a database request
const dummyAsync = (value) => {
return new Promise((resolve) => {
setTimeout(resolve, Math.random() * 2000, value);
});
}
//Wrapper for components that manages their "lifecycle"
const Lifecycle = fn => {
//Sometimes
const useState = async () => {
console.log ("Use State of fn " + fn.name)
//Return the functions name to see its scope
const state = fn.name
const setState = () => { /* ... */ }
await dummyAsync()
return [fn.name, setState]
}
return async (props) => {
//This is the problem. Because an async function is a generator it pauses the execution.
//Thus by the time the first component continues rendering after its first await
//The reference to the useState function gets overwritten by the next function that gets rendered.
Lifecycle.useState = useState;
return await fn(props)
}
}
const render = (cmp, props = {}) => {
return Lifecycle(cmp)(props)
}
//So I need to be able to render multiple components "simultaneously" while maintaining a reference to the correct scope.
(async () => {
const res = await Promise.all([render(Foo), render(Bar),render(Foo), render(Bar),render(Foo), render(Bar), render(Foo), render(Bar),render(Foo), render(Bar)])
console.log ("Rendered", JSON.stringify(res));
})()
//Any idea how I could solve this?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment