Reactivity

Declare state

Update state

Computed state

Templating

Minimal template

Styling

React

import "./style.css";

export default function CssStyle() {

return (

<>

<h1 className="title">I am red</h1>

<button style={{ fontSize: "10rem" }}>I am a button</button>

</>

);

}

Loop

React

export default function Colors() {

const colors = ["red", "green", "blue"];

return (

<ul>

{colors.map((color) => (

<li key={color}>{color}</li>

))}

</ul>

);

}

Event click

React

import { useState } from "react";

export default function Counter() {

const [count, setCount] = useState(0);

function incrementCount() {

setCount((count) => count + 1);

}

return (

<>

<p>Counter: {count}</p>

<button onClick={incrementCount}>+1</button>

</>

);

}

Dom ref

React

import { useEffect, useRef } from "react";

export default function InputFocused() {

const inputElement = useRef(null);

useEffect(() => inputElement.current.focus(), []);

return <input type="text" ref={inputElement} />;

}

Conditional

React

import { useState } from "react";

const TRAFFIC_LIGHTS = ["red", "orange", "green"];

export default function TrafficLight() {

const [lightIndex, setLightIndex] = useState(0);

const light = TRAFFIC_LIGHTS[lightIndex];

function nextLight() {

setLightIndex((lightIndex + 1) % TRAFFIC_LIGHTS.length);

}

return (

<>

<button onClick={nextLight}>Next light</button>

<p>Light is: {light}</p>

<p>

You must

{light === "red" && <span>STOP</span>}

{light === "orange" && <span>SLOW DOWN</span>}

{light === "green" && <span>GO</span>}

</p>

</>

);

}

<script>

const TRAFFIC_LIGHTS = ["red", "orange", "green"];

let lightIndex = $state(0);

const light = $derived(TRAFFIC_LIGHTS[lightIndex]);

function nextLight() {

lightIndex = (lightIndex + 1) % TRAFFIC_LIGHTS.length;

}

</script>

<button onclick={nextLight}>Next light</button>

<p>Light is: {light}</p>

<p>

You must

{#if light === "red"}

<span>STOP</span>

{:else if light === "orange"}

<span>SLOW DOWN</span>

{:else if light === "green"}

<span>GO</span>

{/if}

</p>

Lifecycle

On mount

React

import { useState, useEffect } from "react";

export default function PageTitle() {

const [pageTitle, setPageTitle] = useState("");

useEffect(() => {

setPageTitle(document.title);

}, []);

return <p>Page title: {pageTitle}</p>;

}

On unmount

React

import { useState, useEffect } from "react";

export default function Time() {

const [time, setTime] = useState(new Date().toLocaleTimeString());

useEffect(() => {

const timer = setInterval(() => {

setTime(new Date().toLocaleTimeString());

}, 1000);

return () => clearInterval(timer);

}, []);

return <p>Current time: {time}</p>;

}

Component composition

Props

React

import UserProfile from "./UserProfile.jsx";

export default function App() {

return (

<UserProfile

name="John"

age={20}

favouriteColors={["green", "blue", "red"]}

isAvailable

/>

);

}

Emit to parent

React

import { useState } from "react";

import AnswerButton from "./AnswerButton.jsx";

export default function App() {

const [isHappy, setIsHappy] = useState(true);

function onAnswerNo() {

setIsHappy(false);

}

function onAnswerYes() {

setIsHappy(true);

}

return (

<>

<p>Are you happy?</p>

<AnswerButton onYes={onAnswerYes} onNo={onAnswerNo} />

<p style={{ fontSize: 50 }}>{isHappy ? "😀" : "😥"}</p>

</>

);

}

<script>

import AnswerButton from "./AnswerButton.svelte";

let isHappy = $state(true);

function onAnswerNo() {

isHappy = false;

}

function onAnswerYes() {

isHappy = true;

}

</script>

<p>Are you happy?</p>

<AnswerButton onYes={onAnswerYes} onNo={onAnswerNo} />

<p style="font-size: 50px;">{isHappy ? "😀" : "😥"}</p>

Slot

Slot fallback

Context

React

import { useState } from "react";

import UserProfile from "./UserProfile";

import { UserContext } from "./UserContext";

export default function App() {

const [user, setUser] = useState({

id: 1,

username: "unicorn42",

email: "[email protected]",

});

function updateUsername(newUsername) {

setUser((userData) => ({ ...userData, username: newUsername }));

}

return (

<>

<h1>Welcome back, {user.username}</h1>

<UserContext.Provider value={{ ...user, updateUsername }}>

<UserProfile />

</UserContext.Provider>

</>

);

}

<script>

import { setContext } from "svelte";

import UserProfile from "./UserProfile.svelte";

import createUserState from "./createUserState.svelte.js";

const user = createUserState({

id: 1,

username: "unicorn42",

email: "[email protected]",

});

setContext("user", user);

</script>

<h1>Welcome back, {user.username}</h1>

<UserProfile />

Form input

Input text

React

import { useState } from "react";

export default function InputHello() {

const [text, setText] = useState("Hello world");

function handleChange(event) {

setText(event.target.value);

}

return (

<>

<p>{text}</p>

<input value={text} onChange={handleChange} />

</>

);

}

Checkbox

React

import { useState } from "react";

export default function IsAvailable() {

const [isAvailable, setIsAvailable] = useState(false);

function handleChange() {

setIsAvailable(!isAvailable);

}

return (

<>

<input

id="is-available"

type="checkbox"

checked={isAvailable}

onChange={handleChange}

/>

<label htmlFor="is-available">Is available</label>

</>

);

}

Radio

React

import { useState } from "react";

export default function PickPill() {

const [picked, setPicked] = useState("red");

function handleChange(event) {

setPicked(event.target.value);

}

return (

<>

<div>Picked: {picked}</div>

<input

id="blue-pill"

checked={picked === "blue"}

type="radio"

value="blue"

onChange={handleChange}

/>

<label htmlFor="blue-pill">Blue pill</label>

<input

id="red-pill"

checked={picked === "red"}

type="radio"

value="red"

onChange={handleChange}

/>

<label htmlFor="red-pill">Red pill</label>

</>

);

}

<script>

let picked = $state("red");

</script>

<div>Picked: {picked}</div>

<input id="blue-pill" bind:group={picked} type="radio" value="blue" />

<label for="blue-pill">Blue pill</label>

<input id="red-pill" bind:group={picked} type="radio" value="red" />

<label for="red-pill">Red pill</label>

Select

React

import { useState } from "react";

const colors = [

{ id: 1, text: "red" },

{ id: 2, text: "blue" },

{ id: 3, text: "green" },

{ id: 4, text: "gray", isDisabled: true },

];

export default function ColorSelect() {

const [selectedColorId, setSelectedColorId] = useState(2);

function handleChange(event) {

setSelectedColorId(event.target.value);

}

return (

<select value={selectedColorId} onChange={handleChange}>

{colors.map((color) => (

<option key={color.id} value={color.id} disabled={color.isDisabled}>

{color.text}

</option>

))}

</select>

);

}

<script>

let selectedColorId = $state(2);

const colors = [

{ id: 1, text: "red" },

{ id: 2, text: "blue" },

{ id: 3, text: "green" },

{ id: 4, text: "gray", isDisabled: true },

];

</script>

<select bind:value={selectedColorId}>

{#each colors as color}

<option value={color.id} disabled={color.isDisabled}>

{color.text}

</option>

{/each}

</select>

Webapp features

Render app

React

<!doctype html>

<html>

<body>

<div id="app"></div>

<script type="module" src="./main.jsx"></script>

</body>

</html>

Svelte 5

<!doctype html>

<html>

<body>

<div id="app"></div>

<script type="module" src="./app.js"></script>

</body>

</html>

Fetch data

React

import useFetchUsers from "./useFetchUsers";

export default function App() {

const { isLoading, error, data: users } = useFetchUsers();

return (

<>

{isLoading ? (

<p>Fetching users...</p>

) : error ? (

<p>An error occurred while fetching users</p>

) : (

users && (

<ul>

{users.map((user) => (

<li key={user.login.uuid}>

<img src={user.picture.thumbnail} alt="user" />

<p>

{user.name.first} {user.name.last}

</p>

</li>

))}

</ul>

)

)}

</>

);

}

<script>

import useFetchUsers from "./useFetchUsers.svelte.js";

const response = useFetchUsers();

</script>

{#if response.isLoading}

<p>Fetching users...</p>

{:else if response.error}

<p>An error occurred while fetching users</p>

{:else if response.users}

<ul>

{#each response.users as user}

<li>

<img src={user.picture.thumbnail} alt="user" />

<p>

{user.name.first}

{user.name.last}

</p>

</li>

{/each}

</ul>

{/if}