Last active
January 27, 2024 13:51
-
-
Save mindplay-dk/1cd7f487b6ed7a5ab98483cf061b3822 to your computer and use it in GitHub Desktop.
reactive JS π€ everything is a signal? π€·ββοΈ
This file contains 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 know this is probably bonkers and there must be a million reasons this wouldn't | |
actually work, but hear me out... what if variables were reactive by default?? π | |
*/ | |
function fetchTodayFortune() { | |
return fetch("https://api.example.com/fortune") | |
.then((response) => response.json()) | |
.then((data) => data.message) | |
.catch((error) => { | |
throw error; | |
}); | |
} | |
function untilResolved(promise, fallback) { | |
// Create a reactive variable to hold the result/fallback/error message: | |
let result = fallback; | |
// Start the promise and update the result when it resolves. | |
promise.then((value) => { | |
result = value; | |
}).catch(() => { | |
result = "sorry, no fortune available today..." | |
}); | |
return result; | |
} | |
// Fetch today's fortune and store it in a variable with an initial "loading" message. | |
const fortune = untilResolved(fetchTodayFortune(), "loading..."); | |
function renderForm() { | |
// Declare local reactive variables | |
let firstName = ""; | |
let lastName = ""; | |
let fullName = firstName + " " + lastName; | |
// Counter for tracking how long the form has been open. | |
let counter = 0; | |
// Effect for updating the counter every second. | |
const intervalId = setInterval(() => { | |
counter += 1; | |
}, 1000); | |
// Render the form and components. | |
return ( | |
<div> | |
<input | |
type="text" | |
placeholder="First Name" | |
value={firstName} | |
onInput={(event) => { | |
firstName = event.target.value; | |
}} | |
/> | |
<input | |
type="text" | |
placeholder="Last Name" | |
value={lastName} | |
onInput={(event) => { | |
lastName = event.target.value; | |
}} | |
/> | |
<p>Welcome, {fullName}!</p> | |
<p>Form open for: {counter} seconds</p> | |
<p>Today's Fortune: {fortune}</p> | |
<button disabled={!firstName || !lastName}>Continue</button> | |
</div> | |
) finally { | |
// Cleanup function to clear the interval when the component is unmounted. | |
clearInterval(intervalId); | |
// (finally blocks can be attached to any value and run when garbage-collected, | |
// in this case when the element is removed from the DOM.) | |
}; | |
} | |
// Mount two instances of the form to the DOM. | |
const form1 = renderForm(); | |
const form2 = renderForm(); | |
const appElement = document.getElementById("app"); | |
appElement.appendChild(form1); | |
appElement.appendChild(form2); | |
// Example: Remove one of the forms, and the cleanup function is called. | |
setTimeout(() => { | |
appElement.removeChild(form2); | |
// The cleanup function for form2 will automatically clear its interval timer. | |
}, 5000); // Remove form2 after 5 seconds as an example. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment