Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Vue.js-like reactive state
<script>
let activeEffect
class Dep {
subscribers = new Set()
depend() {
if (activeEffect) this.subscribers.add(activeEffect)
}
notify() {
this.subscribers.forEach((sub) => sub())
}
}
function watchEffect(fn) {
const wrappedFn = () => {
activeEffect = wrappedFn
// clean up the deps
fn()
activeEffect = null
}
wrappedFn()
}
function reactive(obj) {
Object.keys(obj).forEach((key) => {
const dep = new Dep()
let value = obj[key]
Object.defineProperty(obj, key, {
get() {
dep.depend()
return value
},
set(newValue) {
if (newValue !== value) {
value = newValue
dep.notify()
}
},
})
})
return obj
}
// -------------------------
const state = reactive({
count: 1,
name: 'Marc',
})
watchEffect(() => {
console.log('👻 state changed', state.count, state.name)
})
setTimeout(() => {
state.count++
state.name = 'Johnny'
}, 1000)
setTimeout(() => {
state.count++
}, 2000)
setTimeout(() => {
state.count++
}, 3000)
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.