Last active
February 12, 2022 05:05
-
-
Save C5H8NNaO4/4b229eadddfd626c1434f461a7c5b55d to your computer and use it in GitHub Desktop.
How to maintain a reference to the correct scope when calling useState?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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