Non-violable states β
Picture this code:
ts
import { openModal, closeModal } from '@/modals'
let isModalOpened = false
let theModalContent: string | undefined
effect(() => {
if (isModalOpened) {
openModal(theModalContent)
}
})
function onButtonClick() {
isModalOpened = true
theModalContent = 'Hello World'
}
function onEscapePressed() {
isModalOpened = false
}
This code assumes the content has to be generated each time. It has 2 major flaws:
1st flaw β an action should always happen -> no if
β
This is what reactivity truly means: a state/signal value changed -> something must happen.
Here if isModalOpened
switches to true
, the modal is getting opened ; but if isModalOpened
switches to false
, nothing happens.
Letβs fix that:
ts
effect(() => {
if (isModalOpened) {
openModal(theModalContent)
}
isModalOpened
? openModal(theModalContent)
: closeModal()
})
2nd flaw β this modal state is violable β
I can have isModalOpened = true
with theModalContent = undefined
. Thatβs problematic, it literally means "I show a modal but I have nothing to show".
How can we make that state non-violable? I see 2 options:
Option #1 β display the modal depending on whether we have some modal content β
ts
import { openModal, closeModal } from '@/modals'
let isModalOpened = false
let theModalContent: string | undefined
effect(() => {
isModalOpened
theModalContent
? openModal(theModalContent)
: closeModal()
})
function onButtonClick() {
isModalOpened = true
theModalContent = 'Hello World'
}
function onEscapePressed() {
isModalOpened = false
theModalContent = undefined
}
Do you notice how we cannot make mistakes anymore?
- We have content to display, we have a modal
- We have no content to display, we don't have a modal
It also removed a lot of code. Double win πͺ.
Option #2 βΒ a more verbose yet more explicit state β
ts
import { openModal, closeModal } from '@/modals'
let isModalOpened = false
let theModalContent: string | undefined
type MyModal =
| { isOpened: true, content: string }
| { isOpened: false }
let myModal: MyModal = { isOpened: false }
effect(() => {
isModalOpened
? openModal(theModalContent)
myModal.isOpened
? openModal(myModal.content)
: closeModal()
})
function onButtonClick() {
isModalOpened = true
theModalContent = 'Hello World'
myModal = { isOpened: true, content: 'Hello World' }
}
function onEscapePressed() {
isModalOpened = false
myModal = { isOpened: false }
}
Both examples are completely valid and non-violable.