A | B | C | |
---|---|---|---|
0 | x | y | x + y |
1 | |||
2 |
SyntaxError: Failed to execute 'querySelector' on 'Element': '#1otSL' is not a valid selector.
function signal(value) {
return {
get value() {
// track
return value
},
set value(newValue) {
value = newValue
// notify all trackers
}
}
}
mutable vs immutable API | |||||||
State is always in sync | |||||||
Re-render | |||||||
Works outside the component | |||||||
Works outside the framework |
mutable vs immutable API | ||||||
State is always in sync | ||||||
Re-render | ||||||
Works outside the component | ||||||
Works outside the framework |
Count: 0
export function Component() {
function increase() {
}
return (
<>
<p>Count: 0</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState } from 'react'
export function Component() {
const [count, setCount] = useState(0)
function increase() {
setCount(count + 1)
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState } from 'react'
export function Component() {
const [count, setCount] = useState(0)
const double = count * 2
function increase() {
setCount(count + 1)
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState, useMemo } from 'react'
export function Component() {
const [count, setCount] = useState(0)
const double = useMemo(() => count * 2, [count])
function increase() {
setCount(count + 1)
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState } from 'react'
export function Component() {
const [count, setCount] = useState(0)
const double = count * 2
function increase() {
setCount(count + 1)
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState, useEffect } from 'react'
export function Component() {
const [count, setCount] = useState(0)
const double = count * 2
useEffect(() => console.log(double), [double])
function increase() {
setCount(count + 1)
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState, useEffect } from 'react'
export function Component() {
const [count, setCount] = useState(0)
const double = count * 2
useEffect(() => console.log(double), [double])
function increase() {
setCount(count + 1)
console.log(count) // 0
console.log(double) // 0
}
return (
<>
<p>Count: { count }</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { useState, useEffect } from 'react'
const [count, setCount] = useState(0) // ❌
export function Component() {
const double = count * 2
useEffect(() => console.log(double), [double])
function increase() {
setCount(count + 1)
console.log(count) // 0
console.log(double) // 0
}
return (
<>
<p>Count: { count }</p>
<button onClick={increase}>Bump</button>
</>
)
}
mutable vs immutable API | Immutable |
State is always in sync | |
Re-render | |
Works outside the component | |
Works outside the framework |
<script setup>
function increase() {
}
</script>
<template>
<p>Count: 0</p>
<button @click="increase">Bump</button>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increase() {
count.value++
}
</script>
<template>
<p>Count: {{count}}</p>
<button @click="increase">Bump</button>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({ count: 0})
function increase() {
state.count++
}
</script>
<template>
<p>Count: {{state.count}}</p>
<button @click="increase">Bump</button>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increase() {
count.value++
}
</script>
<template>
<p>Count: {{count}}</p>
<button @click="increase">Bump</button>
</template>
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
function increase() {
count.value++
}
</script>
<template>
<p>Count: {{count}}</p>
<button @click="increase">Bump</button>
</template>
<script setup>
import { ref, computed, watchEffect } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
watchEffect(() => console.log(double))
function increase() {
count.value++
}
</script>
<template>
<p>Count: {{count}}</p>
<button @click="increase">Bump</button>
</template>
<script setup>
import { ref, computed, watchEffect } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
watchEffect(() => console.log(double))
function increase() {
count.value++
console.log(count.value) // 1
console.log(double.value) // 2
}
</script>
<template>
<p>Count: {{count}}</p>
<button @click="increase">Bump</button>
</template>
state.js:
import { ref, computed, watchEffect } from 'vue'
export const count = ref(0)
const double = computed(() => count.value * 2)
watchEffect(() => console.log(double))
Component.vue:
<script setup>
import { count } from 'state.js'
function increase() {
count.value++
}
</script>
<template>
<p>Count: {{count}}</p>
<button @click="increase">Bump</button>
</template>
SyntaxError: Failed to execute 'querySelector' on 'Element': '#4QXF9' is not a valid selector.
mutable vs immutable API | Mutable |
State is always in sync | |
Re-render | |
Works outside the component | |
Works outside the framework |
import { createSignal, createEffect } from 'solid-js'
export function Component() {
const [count, setCount] = createSignal(0)
const double = () => count() * 2
createEffect(() => console.log(double()))
function increase() {
setCount(count() + 1)
}
return (
<>
<p>Count: { count() }</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { createSignal, createEffect } from 'solid-js'
export function Component() {
const [count, setCount] = createSignal(0)
const double = () => count() * 2
createEffect(() => console.log(double()))
function increase() {
setCount(count() + 1)
console.log(count()) // 1
console.log(double()) // 2
}
return (
<>
<p>Count: { count() }</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { createSignal, createEffect } from 'solid-js'
const [count, setCount] = createSignal(0)
const double = () => count() * 2
createEffect(() => console.log(double()))
function increase() {
setCount(count() + 1)
}
export function Component() {
return (
<>
<p>Count: { count() }</p>
<button onClick={increase}>Bump</button>
</>
)
}
mutable vs immutable API | Immutable |
State is always in sync | |
Re-render | |
Works outside the component | |
Works outside the framework |
export function Component() {
function increase() {
}
return (
<>
<p>Count: 0</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { signal } from '@preact/signals'
export function Component() {
const count = signal(0)
function increase() {
count.value++
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { signal, computed } from '@preact/signals'
export function Component() {
const count = signal(0)
const double = computed(() => count.value * 2)
function increase() {
count.value++
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { signal, computed, effect } from '@preact/signals'
export function Component() {
const count = signal(0)
const double = computed(() => count.value * 2)
effect(() => console.log(double.value))
function increase() {
count.value++
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { signal, computed, effect } from '@preact/signals'
export function Component() {
const count = signal(0)
const double = computed(() => count.value * 2)
effect(() => console.log(double.value))
function increase() {
count.value++
console.log(count.value) // 1
console.log(double.value) // 2
}
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
import { signal, computed, effect } from '@preact/signals'
const count = signal(0)
const double = computed(() => count.value * 2)
effect(() => console.log(double.value))
function increase() {
count.value++
}
export function Component() {
return (
<>
<p>Count: {count}</p>
<button onClick={increase}>Bump</button>
</>
)
}
mutable vs immutable API | Mutable |
State is always in sync | |
Re-render | |
Works outside the component | |
Works outside the framework |
import { Component } from '@angular/core'
@Component({
selector: 'count-component',
templateUrl: './count.component.html',
})
export class CountComponent {
increase() {
}
}
import { Component, signal } from '@angular/core'
@Component({
selector: 'count-component',
templateUrl: './count.component.html',
})
export class CountComponent {
count = signal(0)
increase() {
this.count.set(this.count() + 1)
}
}
import { Component, signal, computed } from '@angular/core'
@Component({
selector: 'count-component',
templateUrl: './count.component.html',
})
export class CountComponent {
count = signal(0)
double = computed(() => this.count() * 2)
increase() {
this.count.set(this.count() + 1)
}
}
import { Component, signal, computed, effect } from '@angular/core'
@Component({
selector: 'count-component',
templateUrl: './count.component.html',
})
export class CountComponent {
count = signal(0)
double = computed(() => this.count() * 2)
constructor() {
effect(() => console.log(this.double()))
}
increase() {
this.count.set(this.count() + 1)
}
}
import { Component, signal, computed, effect } from '@angular/core'
@Component({
selector: 'count-component',
templateUrl: './count.component.html',
})
export class CountComponent {
count = signal(0)
double = computed(() => this.count() * 2)
constructor() {
effect(() => console.log(this.double()))
}
increase() {
this.count.set(this.count() + 1)
console.log(this.count()) // 1
console.log(this.double()) // 2
}
}
import { Component, signal, computed, effect } from '@angular/core'
const count = signal(0)
const double = computed(() => count() * 2)
@Component({
selector: 'count-component',
templateUrl: './count.component.html',
})
export class CountComponent {
count = count
double = double
constructor() {
effect(() => console.log(double()))
}
increase() {
count.set(count() + 1)
}
}
SyntaxError: Failed to execute 'querySelector' on 'Element': '#62rXY' is not a valid selector.
mutable vs immutable API | Immutable |
State is always in sync | |
Re-render | |
Works outside the component | (2/3) |
Works outside the framework | (2/3) |
<script>
let count = 0
$: double = count * 2
function increase() {
count++
}
</script>
<p>Count: { count }</p>
<button on:click={increase}>Bump</button>
<script>
let count = $state(0)
const double = $derived(count * 2)
function increase() {
count++
}
</script>
<p>Count: { count }</p>
<button on:click={increase}>Bump</button>
<script>
let count = $state(0)
const double = $derived(count * 2)
$effect(() => console.log(double))
function increase() {
count++
}
</script>
<p>Count: { count }</p>
<button on:click={increase}>Bump</button>
<script>
let count = $state(0)
const double = $derived(count * 2)
$effect(() => console.log(double))
function increase() {
count++
console.log(count) // 1
console.log(double) // 2
}
</script>
<p>Count: { count }</p>
<button on:click={increase}>Bump</button>
state.js:
export let count = $state(0) // ❌
state.svelte.js:
class Count {
value = $state(0)
}
export const count = new Count()
v4 | v5 | |
---|---|---|
mutable vs immutable API | Mutable | Mutable |
State is always in sync | ||
Re-render | ||
Works outside the component | ||
Works outside the framework |
State | useState | ref /reactive | createSignal | signal | signal | $state |
Computed | useMemo | computed | () => | computed | computed | $derived |
Effect | useEffect | watchEffect | createEffect | effect | effect | $effect |
mutable vs immutable API | Immutable | Mutable | Immutable | Mutable | Immutable | Mutable |
State is always in sync | ||||||
Re-render | ||||||
Works outside the component | (2/3) | |||||
Works outside the framework | (2/3) |