Upgrade to Pro — share decks privately, control downloads, hide ads and more …

60分で学ぶ最新Webフロントエンド

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for mizdra mizdra PRO
April 17, 2026

 60分で学ぶ最新Webフロントエンド

2026/04/16 に「技育CAMPアカデミア」で話したスライドです。2025 年のはてなインターンの講義資料 (https://speakerdeck.com/hatena/internship-2025-frontend) に手を加えたものになってます。

https://talent.supporterz.jp/events/b4d7e64d-d315-4e61-b6cc-319e5a541ae9/

Avatar for mizdra

mizdra PRO

April 17, 2026

More Decks by mizdra

Other Decks in Technology

Transcript

  1. ඞཁͳ஌ࣝͷҰྫ • Webϖʔδ/ϒϥ΢β/αʔόͷؔ܎ੑɾ໾ׂ • HTML/CSS/JavaScript (ݴޠ) • React, Next.js (View

    ϥΠϒϥϦ/ϑϨʔϜϫʔΫ) • XSS, CSP (ηΩϡϦςΟ) • Web Vitals (ύϑΥʔϚϯε) • ΞΫηγϏϦςΟ • bundler, linter, formatter, test runner (։ൃπʔϧ) ٕҭCAMPΞΧσϛΞ 4
  2. ϑϩϯτΤϯυ΁ͷΑ͋͘Δҹ৅ • ʮ֮͑Δ͜ͱ͕ଟ͍ʯʮٕज़ͷྲྀΕ͕ૣ͍ʯ • ϑϩϯτΤϯυ͸Ϣʔβʹۙͯ͘ɺίʔσΟϯάਓޱ͕ଟ͍ྖҬ • ͦͷͨΊɺසൟʹ৽ٕज़͕ग़ͯ͘Δ 1 • ৽৘ใΛશ෦௥͍ͬͯͯ͸େม

    • ޲͖߹͍ํΛม͑Δ΂͖ • ྲྀߦΛ௥͏ͷ΋ྑ͍͚Ͳ...ͦͷٕज़͕ొ৔ͨ͠എܠΛߟ͑Α͏ • ϥΠϒϥϦͷ࢖͍ํΛ֮͑Δͷ΋ྑ͍͚Ͳ...௕͘௨༻͢Δ஌ࣝ΋਎ʹ͚ͭΑ͏ 1 ॾઆ͋Γ·͢ɻ ٕҭCAMPΞΧσϛΞ 5
  3. ม਺એݴͱϓϦϛςΟϒܕ // ม਺એݴ (const Λ༏ઌͯ͠࢖͏) let a = "a" //

    ্ॻ͖Մೳ const b = "b" // ্ॻ͖ෆՄೳ // ϓϦϛςΟϒܕ const name = "hatena" // string const age = 20 // number const isStudent = true // boolean const undef = undefined // undefined const nul = null // null ٕҭCAMPΞΧσϛΞ 9
  4. ΦϒδΣΫτɾ഑ྻ const user = { id: "hatena", age: 20 }

    user.id // "1234" const arr = [1, 2, 3] arr[0] // 1 ٕҭCAMPΞΧσϛΞ 10
  5. ؔ਺ // function એݴ function add(a, b) { return a

    + b } // Arrow Function (؆ܿʹؔ਺Λॻ͘ߏจ) const add = (a, b) => a + b const hello = name => `Hello, ${name}` ٕҭCAMPΞΧσϛΞ 11
  6. Nullish coalescing operator ?? • a ?? b ͷΑ͏ʹͯ͠࢖͏ •

    ࠨล͕ undefined or null ͷ࣌ʹӈลͷ஋Λฦ͢ • ͦΕҎ֎ͳΒࠨลͷ஋Λฦ͢ function greet(name) { return `Hello, ${name ?? "mizdra"}!` } σϑΥϧτ஋ʹ fallback ͤ͞ΔͷʹΑ͘࢖͏ɻ ٕҭCAMPΞΧσϛΞ 12
  7. Optional chaining ?. • a?.b ͷΑ͏ʹॻ͘ • a ͕ null

    ·ͨ͸ undefined ͷͱ͖͸ undefined Λฦ͢ • ͦΕҎ֎ͷͱ͖͸௨ৗ௨ΓϓϩύςΟΞΫηεΛߦ͏ const userId1 = session.user?.id; // const userId1 = session.user ? session.user.id : undefined; ͱಉ͡ • ؔ਺ݺͼग़͠ͱ΋૊Έ߹ΘͤΒΕΔ const result = someObject?.someMethod?.(arg1, arg2); ٕҭCAMPΞΧσϛΞ 13
  8. Spread Syntax • ... Λ࢖͏ͱ഑ྻ΍ΦϒδΣΫτΛల։ग़དྷΔ const nums = [1, 2]

    const moreNums = [...nums, 5] // [1, 2, 5] const obj1 = { a: "foo", b: "bar" } const obj2 = { c: "baz" } const merged = { ...obj1, ...obj2 } // {a: "foo", b: "bar", c: "baz"} ٕҭCAMPΞΧσϛΞ 14
  9. Pending ॳظঢ়ଶ ੒ޭ (resolve) ࣦഊ (reject) Fulfilled ඇಉظॲཧ͕੒ޭ Rejected ඇಉظॲཧ͕ࣦഊ

    Promise • ඇಉظॲཧͷ݁ՌΛද͢ΦϒδΣΫτ 2 • 3ͭͷঢ়ଶΛදݱͰ͖Δ • Pending: ॳظঢ়ଶɻ੒ޭ΋ࣦഊ΋͍ͯ͠ͳ ͍ɻ • Fulfilled: ඇಉظॲཧ͕੒ޭͨ͠ • Rejected: ඇಉظॲཧ͕ࣦഊͨ͠ • Pending => Fulfilled or Rejected ͷॱͰঢ়ଶ͕ มԽ 2 Promise ͸ඇಉظॲཧΛѻ͏ͨΊͷΦϒδΣΫτͰɺJavaScript ͷඇಉ ظॲཧͷجຊతͳ࢓૊ΈͰ͢ɻৄࡉ͸෇࿥ʮPromise ʹ͍ͭͯʯΛࢀর ͍ͯͩ͘͠͞ɻ ٕҭCAMPΞΧσϛΞ 15
  10. Promise ͷੜ੒ํ๏ • new Promise((resolve, reject) => {...}) Ͱ Promise

    Λੜ੒ • resolve ΛݺͿͱ Fulfilled ʹͳΓɺreject ΛݺͿͱ Rejected ʹͳΔ function sleep(ms) { return new Promise((resolve, reject) => { if (typeof ms !== "number") { reject(new Error("ms must be a number")) return } setTimeout(() => { resolve(ms) }, ms) }) } ٕҭCAMPΞΧσϛΞ 16
  11. fetch Λ࢖ͬͨྫ • fetch ͸ HTTP ϦΫΤετΛૹ৴͢Δ API • ϦΫΤετૹ৴͸ඇಉظॲཧͳͷͰɺPromise

    Λฦ͢Α͏ʹͳͬͯΔ const promise = fetch("https://api.example.com/user/1") // ᶃ .then((res) => /* ᶄ */ res.json()) .then((json) => /* ᶅ */ console.log(json.user)) .catch((e) => /* ᶆ */ console.error(e)) console.log(promise) // ᶇ • ᶃ => ᶇ => ᶄ => ᶅ => ᶆ ͷॱʹ࣮ߦ͞ΕΔ͜ͱʹ஫ҙ • ίʔϧόοΫؔ਺͸ඇಉظॲཧ͕׬ྃޙʹ࣮ߦ͞ΕΔ (஗Ԇ͞ΕΔ) ٕҭCAMPΞΧσϛΞ 18
  12. async/await const getUser = async (id) => { try {

    const res = await fetch(`https://api.example.com/user/${id}`) const json = await res.json() const user = json.user console.log(`${user.name}ͷid͸${user.id}`) return user } catch (e) { console.error(e) throw new Error("error reason: *********") } } ΤϥʔϋϯυϦϯάʹ͸ try {} catch (e) {} Λ࢖༻͠·͢ɻ ٕҭCAMPΞΧσϛΞ 20
  13. async/await • async function ࣗମ΋҉໧తʹ Promise Λฦ͢ • ؔ਺ͷฦΓ஋ʹରͯ͠ɺthen Λݺͼग़ͤΔ

    getUser(1) .then(console.log) // {id: 1, name: 'hatena'} .catch(console.error) ٕҭCAMPΞΧσϛΞ 21
  14. ECMAScript Modules (ES Modules) • ϓϩάϥϜΛϞδϡʔϧͱ͍͏୯Ґʹ෼ׂ͢Δػೳ • 1 ϑΝΠϧ ==

    1 Ϟδϡʔϧ • είʔϓ͸Ϟδϡʔϧ͝ͱ • ؔ਺΍ม਺ͳͲΛ import/export Ͱ͖Δ ٕҭCAMPΞΧσϛΞ 22
  15. named export, named import • ม਺એݴ΍ؔ਺એݴʹ export Λ෇Ճ͢Δͱ named export

    Ͱ͖Δ // lib.js export const logLevel = { WARN: "warn", ERROR: "error", }; export function log(message, level) {/* ... */} // main.js import { logLevel, log } from './lib.js' ٕҭCAMPΞΧσϛΞ 23
  16. default export // lib.js export default function (message, level) {/*

    ... */} // main.js import awesome from "./lib" • export default ͱ͍͏ΩʔϫʔυͰ΋ export Ͱ͖Δ • ໊લΛ෇͚ͣʹΤΫεϙʔτͰ͖Δ • import ࣌ʹ೚ҙͷ໊લΛઃఆͰ͖Δ • export default Ͱ͖Δͷ͸ɺ1ͭͷϞδϡʔϧʹ͖ͭ 1 ͚ͭͩ ٕҭCAMPΞΧσϛΞ 24
  17. TypeScript ʹ͍ͭͯ • JavaScript ʹ੩తܕ෇͚Λಋೖͨ͠ݴޠ • JavaScript + ܕ஫ऍ •

    ίϯύΠϥ (tsc) ͰܕνΣοΫΛߦ͏ • ݱ୅Ͱ͸ੜͷ JavaScript ॻ͘ΑΓɺTypeScript Ͱॻ͘͜ͱ͕ଟ͍ function hello(name: string): string { return `Hello, ${name}!` } const result = hello(1) // ^ // Type Error: Argument of type '1' is not assignable to parameter of type 'string'. ٕҭCAMPΞΧσϛΞ 26
  18. tsc: TypeScript compiler • TypeScript ݴޠͷͨΊͷίϯύΠϥ • ओͳػೳ • ܕνΣοΫΛ͢Δ

    • TypeScript Ͱॻ͔ΕͨίʔυΛ JavaScript ʹม׵͢Δ • ม׵ͱݴͬͯ΋ɺܕΞϊςʔγϣϯ౳ͷ࡟আ͘Β͍ ٕҭCAMPΞΧσϛΞ 28
  19. ϓϦϛςΟϒܕɾϦςϥϧܕ const a: number = 10 const b: boolean =

    false const c: string = "hello" const d: null = null const e: "hello" = "hello" const f: "hello" = "world" // Type Error const g: 10 = 10 const h: 10 = 20 // Type Error ٕҭCAMPΞΧσϛΞ 31
  20. ഑ྻܕɾΦϒδΣΫτܕ const arr: string[] = ["hello", "world"] const arr2: Array<number>

    = [1, 2, 3, 5, 8] const arr3: [string, number] = ["year", 2021] // λϓϧ(Tuple)ܕͱ΋ const person: { name: string age: number address?: string // ? Λ෇͚ΔͱΦϓγϣφϧʹͳΔ } = { name: "john", age: 21, // address: "tokyo" // ͋ͬͯ΋ͳͯ͘΋ྑ͍ } ٕҭCAMPΞΧσϛΞ 32
  21. ܕͷਪ࿦ • TypeScript ͸ίʔυ͔ΒܕΛ༧ଌͯ͠࠾༻͢Δ (ਪ࿦) • Ͱ͖Δ͚ͩਪ࿦ͤ͞ɺܕΞϊςʔγϣϯ͸লུ͢Δͷ͕Ұൠత const a =

    10 // number const b = false // boolean const c = ["hello", "world"] // string[] ٕҭCAMPΞΧσϛΞ 33
  22. Union Type (߹ซܕ) ෳ਺ͷܕͷ͍ͣΕ͔Λຬͨ͢ɻ type Color = "red" | "green"

    | "blue" | "yellow" | "purple" const c: Color = "red" const d: Color = "black" // Type Error ٕҭCAMPΞΧσϛΞ 35
  23. Narrowing • ؇͍ܕΛΑΓڱ͍ܕʹߜΓࠐΉςΫχοΫ • typeof ԋࢉࢠͳͲΛ࢖͏ͱɺܕͷߜΓࠐΈ͕Ͱ͖Δ // ίʔυ͸ https://www.typescriptlang.org/docs/handbook/2/narrowing.html ΑΓҾ༻

    function padLeft(padding: number | string, input: string): string { if (typeof padding === "number") { // ͜ͷϒϩοΫ಺Ͱ͸ `padding` ͸ `number` ܕ return " ".repeat(padding) + input } else if (typeof padding === "string") { // ͜ͷϒϩοΫ಺Ͱ͸ `padding` ͸ `string` ܕ return padding + input } } ٕҭCAMPΞΧσϛΞ 36
  24. in ԋࢉࢠ • JavaScript ʹ͋Δԋࢉࢠ • TypeScript Ͱ͸ɺಛఆͷϓϩύςΟΛ࣋ͭܕ΁ͱߜΓࠐΊΔ type Fish

    = { name: string, swim: () => void } type Bird = { name: string, fly: () => void } const move = (x: Fish | Bird) => { if ("swim" in x) { // Fish ܕʹߜΓࠐ·ΕΔ return x.swim() } // ͜͜Ͱ͸ Bird ܕʹߜΓࠐ·ΕΔ return x.fly() } ٕҭCAMPΞΧσϛΞ 37
  25. Tagged Union Types • Union Type ͷݸʑͷܕʹɺkind ͷΑ͏ͳϓϩύςΟΛ࣋ͨͤΔςΫχοΫͷ͜ͱ • x.kind

    === ... ͰܕͷߜΓࠐΈ͕Ͱ͖Δ type Fish = { kind: "fish" swim: () => void } type Bird = { kind: "bird" fly: () => void } const move = (x: Fish | Bird) => { if (x.kind === "fish") { return x.swim() } return x.fly() } ٕҭCAMPΞΧσϛΞ 38
  26. as Λ༻͍ͨܕΞαʔγϣϯ(Type Assertion) • ਪ࿦͞ΕͨܕΛ্ॻ͖Ͱ͖Δߏจ • ਪ࿦͞Εͨܕ͕ظ଴௨ΓͰͳ͍৔߹ʹ࢖͏ // ຊདྷ͸ `Element

    | null` ͕ͩɺ`HTMLTextAreaElement` ʹ্ॻ͖͢Δ const editor = document.querySelector(".editor") as HTMLTextAreaElement ٕҭCAMPΞΧσϛΞ 39
  27. ஫ҙ: as Ͱ͸࣮ߦ࣌ͷڍಈ͸มΘΒͳ͍ • ͋͘·Ͱ TypeScript ίϯύΠϥ಺Ͱ࢖ΘΕΔܕ͕มΘΔ͚ͩ • "str" as

    number ͱॻ͍ͯ΋ɺจࣈྻ͔Β਺஋ʹม׵͞Εͳ͍ const a = "1" as number console.log(a) // "1" console.log(typeof a) // "string" ٕҭCAMPΞΧσϛΞ 40
  28. any ͱ unknown any • ͲΜͳ஋Ͱ΋ೖΕΒΕΔܕ -ϓϩύςΟΞΫηε͕ܕΤ ϥʔʹͳΒͳ͍ let val:

    any = { foo: 1 } val.foo // ΤϥʔʹͳΒͳ͍ val.bar // ΤϥʔʹͳΒͳ͍ unknown • ͲΜͳ஋Ͱ΋ೖΕΒΕΔܕ • ϓϩύςΟΞΫηε͕ܕΤ ϥʔʹͳΔ const val: unknown = { foo: 1 } val.foo // ΤϥʔʹͳΔ val.bar // ΤϥʔʹͳΔ ٕҭCAMPΞΧσϛΞ 41
  29. Ͳ͏͍͏࣌ʹ࢖͏? ֎෦ API ͔ΒͷϨεϙϯεͳͲɺܕ͕ෆ໌ͳ஋Λѻ͏ͱ͖ʹ࢖͏ɻ const res = await fetch("/api/data") //

    ·ͣ unknown ͱͯ͠ड͚औΔ const data: unknown = await res.json() // Narrowing ͰߜΓࠐΉ if ( (typeof data === "object" && data !== null) && ("name" in data && typeof data.name === "string") ) { // ͜ͷதͰ͸ data.name ͸ string ܕ console.log("Hello, " + data.name) } ٕҭCAMPΞΧσϛΞ 42
  30. ؔ਺ function add(x: number, y: number): number { return x

    + y } // Arrow Function Ͱ΋ಉ༷ const add = (x: number, y: number): number => { return x + y } // ୅ೖࣜ (=) ͷࠨลʹॻ͘͜ͱ΋Ͱ͖Δ const add: (x: number, y: number) => number = (x, y) => { return x + y } // ಛʹ return ͠ͳ͍৔߹͸ void Λࢦఆ͢Δ const a: () => void = () => { console.log("a") } ٕҭCAMPΞΧσϛΞ 43
  31. ܕҾ਺(Generics) • ܕΛҾ਺ͱͯ͠౉ͤΔػೳ const getJSON = <T>(url: string): Promise<T> =>

    { // res.json͸anyͱͳΒͣʹܕҾ਺Ͱ౉͞Εͨ΋ͷͱղऍ͞ΕΔ return fetch(url).then<T>((res) => res.json()) } // users ͸ User[] ʹͳΔ const users = await getJSON<User[]>("/api/users") // blogs ͸ Blog[] ʹͳΔ const blogs = await getJSON<Blog[]>("/api/blogs") ٕҭCAMPΞΧσϛΞ 44
  32. TypeScript ͷॻ͖ํͰࠔͬͨΒ? • ެࣜυΩϡϝϯτͷ Handbook Λಡ΋͏ • https://www.typescriptlang.org/docs/handbook/intro.html • Playground

    Ͱࢼ͠ॻ͖͠Α͏ • https://www.typescriptlang.org/play • ೉͍͠ܕͷॻ͖ํ͸ Type Challenges ΛݟͯΈΑ͏ • https://github.com/type-challenges/type-challenges ٕҭCAMPΞΧσϛΞ 45
  33. ίʔυྫ const Greeting = () => { const [name, setName]

    = useState('') return ( <div> <input value={name} onChange={(e) => setName(e.target.value)} /> <p>͜Μʹͪ͸ɺ{name} ͞Μ!</p> </div> ) } ٕҭCAMPΞΧσϛΞ 48
  34. React Λ࢖Θͳ͔ͬͨ࣌ <div> <input id="name" /> <p>͜Μʹͪ͸ɺ<span id="display"></span> ͞Μ!</p> </div>

    <script> document.getElementById('name').addEventListener('change', (e) => { document.getElementById('display').textContent = e.target.value }) </script> ٕҭCAMPΞΧσϛΞ 50
  35. React Λ࢖Θͳ͔ͬͨ࣌ • DOM API Ͱૢ࡞͢Δ • document.getElementById ͰཁૉΛऔͬͯ͘Δ •

    element.addEventListener ͰΠϕϯτϦεφʔΛొ࿥ • ςΩετͷߋ৽͸ element.textContent = "ߋ৽ޙͷςΩετ" • ϚʔΫΞοϓ (HTML෦෼) ͱϩδοΫ (JavaScript෦෼) ͕཭Εͯ ͍Δ ٕҭCAMPΞΧσϛΞ 51
  36. React Λ࢖ͬͨ࣌ const Greeting = () => { const [name,

    setName] = useState('') return ( <div> <input value={name} onChange={(e) => setName(e.target.value)} /> <p>͜Μʹͪ͸ɺ{name} ͞Μ!</p> </div> ) } ٕҭCAMPΞΧσϛΞ 52
  37. React Λ࢖ͬͨ࣌ • DOM API Λ࢖Θͣ؆ܿʹॻ͚Δ 3 • ΠϕϯτϦεφʔ͸ onChange={(e)

    => ...} Ͱొ࿥ • ςΩετͷߋ৽͸ {name} ͱॻ͚ͩ͘ • ϚʔΫΞοϓͱϩδοΫΛۙ͘ʹஔ͚Δ • ϝϯςφϯε͠΍͍͢ 3 Ϣʔβ͕௚઀ DOM API Λ࢖ΘͣʹࡁΉ͚ͩͰɺReact ಺෦Ͱ͸ DOM API ͕࢖ΘΕ͍ͯΔɻ ٕҭCAMPΞΧσϛΞ 53
  38. Virtual DOM (Ծ૝ DOM) • state ͕มΘΔͱ React ͕৽͍͠ Virtual

    DOM Λੜ੒ • લճͱͷࠩ෼Λܭࢉ͠ɺมΘͬͨॴ͚࣮ͩࡍͷ DOM ʹ൓ө ٕҭCAMPΞΧσϛΞ 54
  39. લճͷ Virtual DOM div input value="Alice" p [text] "͜Μʹͪ͸ɺAlice ͞Μ!"

    setName Ͱ ࠶ϨϯμϦϯά ৽͍͠ Virtual DOM div input value="Bob" p [text] "͜Μʹͪ͸ɺBob ͞Μ!" React ͕ࠩ෼Λܭࢉͯ͠൓ө ࣮ࡍͷ DOM div input .value = "Bob" p .textContent = ... "͜Μʹͪ͸ɺBob ͞Μ!" ٕҭCAMPΞΧσϛΞ 55
  40. JSX • JavaScript ʹ HTML ͬΆ͍ه๏Λ௥Ճ֦ͨ͠ுߏจ <h1 className="hello">My name is

    Clementine!</h1> • HTML ͷଐੑ໊Ͱ͸ͳ͘ɺΩϟϝϧέʔεͷ໋໊نଇΛ࢖༻ 4 • class ͸ className ͱॻ͘ • class ͕ JavaScript ͷ༧໿ޠͰ͋ΔͨΊɺผͷ໊લʹͳͬͯΔ 5 5 https://github.com/facebook/react/issues/13525#issuecomment-671892643 4 aria-* ΍ data-* ଐੑ͸ྫ֎Ͱ͢ɻ ٕҭCAMPΞΧσϛΞ 57
  41. ίϯϙʔωϯτΛ૊Έ߹Θͤͯ UI Λߏங͢Δ • ίϯϙʔωϯτ͸૊Έ߹ΘͤΒΕΔ • খ͍͞ίϯϙʔωϯτΛ࢖ͬͯɺΑΓେ͖ͳίϯϙʔωϯτΛ࡞͍ͬͯ͘ const SignupForm =

    () => { return ( <div> <h1>ొ࿥ϑΥʔϜ</h1> <Input type="text" name="username" /> <Input type="password" name="password" /> <Button label="ૹ৴" /> </div> ) } ٕҭCAMPΞΧσϛΞ 59
  42. Props Λ౉͢/ड͚औΔ • ड͚औΔଆ͸ؔ਺ͷୈ 1 Ҿ਺ͰΦϒδΣΫτͱͯ͠ड͚औΔ type Props = {

    name: string } const Welcome = ({ name }: Props) => { return <h1>Welcome {name}</h1> } • ౉͢ଆ(਌ଆ)͸ prop=஋ ͱॻ͘ <Welcome name="John" /> ٕҭCAMPΞΧσϛΞ 61
  43. useState • ίϯϙʔωϯτʹঢ়ଶΛ࣋ ͨͤΔͨΊͷ API const Counter = () =>

    { const [count, setCount] = useState(0) const increaseCount = () => setCount((prevCount) => prevCount + 1) return ( <div> Χ΢ϯτ: {count} <button onClick={increaseCount}>Χ΢ϯτ</button> </div> ) } ٕҭCAMPΞΧσϛΞ 62
  44. Hooks • useState ͸ React ͕ఏڙ͢ΔHookͷҰͭ • Hook ͱ͸ •

    ίϯϙʔωϯτͷதͰঢ়ଶ΍ϥΠϑαΠΫϧͳͲػೳΛѻ͏ ͨΊͷ࢓૊Έ • খ೉͍͠ݴ͍ํΛ͢Δͱɺ෭࡞༻Λѻ͏ͨΊͷ࢓૊Έ ٕҭCAMPΞΧσϛΞ 63
  45. Hooks ͷᎄ ϑοΫͷϧʔϧ – React • ໊લ͸ use ͔Β࢝ΊΔ •

    ίϯϙʔωϯτؔ਺ͷτοϓϨϕϧͰݺͿ • if ͷதͰݺ͹ͳ͍ • early return ͢ΔલʹඞͣݺͿ ٕҭCAMPΞΧσϛΞ 64
  46. useState • useState(ॳظ஋) ͱݺͼग़ͯ͠࢖͏ const Counter = () => {

    const [count, setCount] = useState(0) // count ͸ݱࡏͷ஋Λද͢ม਺ // setCount(1) ͱݺͿͱ count ͕ 1 ʹͳΔ } • setter ΛݺͿͱ಺෦ঢ়ଶ͕ߋ৽͞Εͨ͜ͱ͕ React ʹ௨஌͞ΕΔ • Ծ૝ DOM ͷ࠶ੜ੒ 6ɺൺֱɺ࣮ DOM ͷߋ৽͕ߦΘΕΔ 6 React ʹΑͬͯؔ਺ίϯϙʔωϯτࣗମ͕࠶࣮ߦ͞ΕɺͦͷฦΓ஋͕৽͍͠Ծ૝ DOM ͱͳΓ·͢ ٕҭCAMPΞΧσϛΞ 66
  47. useEffect ͷྫ const Header = ({apiHost}: { apiHost: string })

    => { const [user, setUser] = useState<User | undefined>(undefined) useEffect(() => { fetch(`${apiHost}/api/user`) .then(res => res.json()) .then(data => setUser(data)) }) return ( <header> {user ? `${user.name} ͰϩάΠϯத` : "Loading..."} </header> ) } ٕҭCAMPΞΧσϛΞ 68
  48. useEffectͱґଘ഑ྻ • σϑΥϧτͰ͸ɺΤϑΣΫτ͸Ϩϯμʔ࣌ʹຖճ࣮ߦ͞ΕΔ • useEffect ͷୈ 2 Ҿ਺ (ґଘ഑ྻ) Λ࢖͏ͱɺෆඞཁͳ࣮ߦΛ๷͛Δ

    useEffect(() => { // ґଘ഑ྻͷ஋ (apiHost) ͕มΘ͚ͬͨ࣌ͩ࠶࣮ߦ͞ΕΔ fetch(`${apiHost}/api/user`) .then(res => res.json()) .then(data => setUser(data)) }, [apiHost]) ٕҭCAMPΞΧσϛΞ 69
  49. ґଘ഑ྻ͸ࣗ෼ͰબͿ΋ͷͰ͸ͳ͍ • جຊతʹ͸ɺΤϑΣΫτ͔Βࢀর͞ΕͯΔ஋Λશͯґଘ഑ྻʹೖΕΔ • ESLint + eslint-plugin-react-hooks Λ࢖͏ͱɺೖΕ๨ΕͯΔ஋Λܯࠂͯ͘͠ΕΔ • ͜ͷܯࠂʹै͏ͷ͕ηΦϦʔ

    useEffect(() => { fetch(`${apiHost}/api/user`) .then(res => res.json()) .then(data => setUser(data)) }, []) // ^^ React Hook useEffect has a missing dependency: 'apiHost'. // Either include it or remove the dependency array. ESLint + eslint-plugin-react-hooks ͸ޙ͔Βͷಋೖ͕໘౗ͳͷͰɺॳखͰඞͣಋೖ͠·͠ΐ͏ɻ ٕҭCAMPΞΧσϛΞ 70
  50. useEffect ͱΫϦʔϯΞοϓ • ࣮͸ΤϑΣΫτ͔Βؔ਺ΛฦͤΔ • ΫϦʔϯΞοϓؔ਺ ͱݺ͹ΕΔ • ࣍ͷΤϑΣΫτ͕࣮ߦ͞ΕΔલʹݺ͹ΕΔ useEffect(()

    => { const id = setInterval(() => { console.log("tick") }, duration) return () => { clearInterval(id) // λΠϚʔΛఀࢭ } }, [duration]) ٕҭCAMPΞΧσϛΞ 71
  51. ಠࣗϑοΫ(Custom Hook) Hook ͸૊ΈࠐΈͷ΋ͷ͚ͩͰͳ͘ɺࣗ෼Ͱ࡞Δ͜ͱ΋Ͱ͖Δɻ const useUserStatus = ({ userId })

    => { const [status, setStatus] = useState(null) useEffect(() => { const handler = (user) => { setStatus(user.status) } Api.subscribe(userId, handler) return () => Api.unsubscribe(userId, handler) }) return status } function SomeComponent({ userId }) { const status = useUserStatus({ userId }) return <div>{status}</div> } ٕҭCAMPΞΧσϛΞ 72
  52. ඪ४Խʹ͍ͭͯ ϒϥ΢βͰಈ͘ݴޠ΍ API ͳͲ͸ͦΕͧΕҎԼͷΑ͏ͳ࢓༷Ͱඪ४Խ͞Εͯ·͢ɻ ඪ४Խஂମ ࡦఆ͍ͯ͠Δ࢓༷ WHATWG HTML Living Standard

    DOM Living Standard Fetch Living Standard W3C CSS Specifications WCAG TC39 ECMAScript Internationalization API IETF RFC xxx ٕҭCAMPΞΧσϛΞ 75
  53. ͜͏ͨ͠࢓༷Λ஌Δ͜ͱ͸ॏཁ • API ͷਖ਼͍͠ৼΔ෣͍Λఆ͍ٛͯ͠Δͷ͸࢓༷ • ੈͷதʹެ։͞Ε͍ͯΔ৘ใ͕਺ଟ͋͘Δ͕... • ͦͷ৘ใͷਖ਼͠͞Λ࠷ऴతʹอূ͢ΔͨΊͷ৘ใݯ͕࢓༷ • ྫ͑͹

    JavaScript ΍ CSS ͳͲͷৼΔ෣͍͕ϒϥ΢βؒͰҟͳΔ৔߹... • ͦͷ࣌ʹਖ਼͠͞Λอূͯ͘͠ΕΔͷ͸࢓༷Ͱ͋Δ • ࣮ࡍɺ։ൃΛͯ͠Δͱ࢓༷ͱϒϥ΢βͷࠩҟʹૺ۰͢Δ͜ͱ΋ 7 7 ΢Σϒϒϥ΢βʹόάใࠂΛ͢Δͱ͖ʹ΍Δ͜ͱ - ͺ͚ͨ͢೔ه ٕҭCAMPΞΧσϛΞ 76
  54. ECMAScript ʹ͍ͭͯ • JavaScript ͷඪ४࢓༷͸ ECMAScript ͱݺ͹ΕΔ • Ecma International8ͷதͷ

    Technical Committee 39ʢTC39ʣͱ͍͏ٕज़ҕһձʹΑΓࡦఆ • ݱࡏͷ࢓༷͸https://github.com/tc39/ecma262 • ৗʹ࠷৽൛͕ެ։͞Εଓ͚ͯΔ • ͜͏͍͏ܗࣜΛ Living Standard ͱݺͿ • ຖ೥ 6 ݄ࠒʹ ECMAScript 2021 ͷΑ͏ͳλά͕ଧͨΕΔ • όʔδϣϯ൪߸͕෇༩ͨ͠΋ͷ΋ެ։͞ΕΔ 8 Ecma International ͸ C#ͳͲͷඪ४Խ࡞ۀ΋ߦ͍ͬͯΔ ٕҭCAMPΞΧσϛΞ 77
  55. ECMAScript ͷ Stage • ECMAScript ʹ͸ࣗ༝ʹఏҊ(proposal)Λग़ͤΔ • GitHub ্Ͱ proposal

    ͕ެ։͞ΕΔ • issueɺPRɺTC39 ͷϛʔςΟϯάͳͲͰͷٞ࿦Λܦͯɺ Stage ্͕͕Δ 9 • Stage 4 ʹͳΔͱ࢓༷ʹऔΓࠐ·ΕΔ 9 ੹೚ऀͰ͋ΔνϟϯϐΦϯͷεςʔδΛਐΊ͍ͨͱ͍͏ҙࢥ΋ඞཁ ٕҭCAMPΞΧσϛΞ 78
  56. Stage ͷৄࡉ https://jsprimer.net/basic/ecmascript/ ΑΓҾ༻ɾҰ෦վมɻ εςʔδ εςʔδͷ֓ཁ 0 ΞΠσΞͷஈ֊ 1 ػೳఏҊͷஈ֊

    2 ػೳͷ࢓༷ॻυϥϑτΛ࡞੒ͨ͠ঢ়ଶ 2.7 ࢓༷͕͋Δఔ౓ݻ·ͬͯͯɺ࣮૷લʹϓϩτλΠϓͳͲΛ࡞ ࣮ͬͯݧ͢Δஈ֊ 3 ࢓༷ͱͯ͠͸׬੒͓ͯ͠Γɺϒϥ΢βͷ࣮૷΍ϑΟʔυόο ΫΛٻΊΔஈ֊ 4 ࢓༷ࡦఆ͕׬ྃ͠ɺ2 ͭҎ্ͷ࣮૷͕ଘࡏ͍ͯ͠Δঢ়ଶ ٕҭCAMPΞΧσϛΞ 79
  57. ECMAScript ͷ࢓༷ͱ࣮૷ • Stage 4 ʹͳΔલʹɺϒϥ΢βͳͲʹ࣮૷͞ΕΔ • ࣮૷্ͷࠔ೉͞ɺ࢖༻্΍࢓༷ͷ໰୊ͳͲΛ֬ೝ͢ΔͨΊ • ͦͷաఔͰ࢓༷ʹϑΟʔυόοΫ͕Ͱ͖ͨΓɺ༗༻ੑΛࣔͤΔ

    • Stage 4 ʹͳΔલʹɺpolyfill ΍ Babel ʹΑΔτϥϯεύΠϧ͕α ϙʔτ͞ΕΔ͜ͱ΋ • ϒϥ΢βʹ࣮૷͢ΔΑΓલʹɺϢʔβʹࢼͯ͠΋Β͑Δ ٕҭCAMPΞΧσϛΞ 80
  58. ECMAScript ͸શ͕ͯ Open • ୭Ͱ΋ϓϩϙʔβϧΛग़ͤΔ͠ɺಡΊΔ͠ɺٞ࿦Ͱ͖Δ • ڵຯͷ͋ΔఏҊ͕͋ͬͨΒ೷͍ͨΓɺ࢖ͬͯΈΑ͏ • ϑΟʔυόοΫ͢Ε͹ɺJavaScript ΛΑΓྑ͘Ͱ͖Δ

    10 10 ECMAScript ͷϓϩϙʔβϧ͸ଟ͘ͷ৔߹ɺͦͷఏҊ͕ʮͲͷΑ͏ͳϞνϕʔγϣϯ͕͋Δͷ͔ʯɺʮͲͷΑ͏ ͳ໰୊Λղܾ͢Δͷ͔ʯɺʮͲͷΑ͏ͳϢʔεέʔε͕͋Δͷ͔ʯͳͲ͕ه͞Ε͍ͯΔͷͰɺͦͷ༗༻ੑͳͲΛࣔ ͢͜ͱ΋ߩݙʹܨ͕Γ·͢ɻ ٕҭCAMPΞΧσϛΞ 81
  59. JavaScript API Λࡦఆ͢Δ࢓༷ ࣮͸ɺJavaScript ͷશ͕ͯ ECMAScript Ͱࡦఆ͞ΕͯΔ༁Ͱ͸ແ͍Ͱ͢ɻ ࢓༷ ࡦఆ͍ͯ͠Δ಺༰ ECMAScript

    (TC39) JavaScript ͷߏจ΍جຊతͳ API DOM Living Standard (WHATWG) document.querySelector ͳͲͷ DOM API Fetch Living Standard (WHATWG) fetch API Internationalization API (TC39) Intl.DateTimeFormat ͳͲͷࠃࡍԽ API ٕҭCAMPΞΧσϛΞ 82
  60. ϒϥ΢βϕϯμͱ WHATWG ࢓༷ • Google ͸ HTML ΍ DOM ʹؔΘΔ

    API11ͷఏҊΛ਺ଟ͘ߦͬͯΔ • Chrome ʹ͸औΓࠐ·ΕΔ͕ɺApple ΍ Moziila ͷ൓ରʹΑΓɺඪ४Խ͞Εͳ͍͜ͱ΋ • Chrome ͷ࢓༷τϥοΧʔ: Chrome Platform Status • Apple ΍ Mozilla ͦΕͧΕ͔Βཱ৔Λද໌͢Δ΢ΣϒαΠτ͕͋Δ • Mozilla Specification Positions • Standards Positions | Webkit • W3C ಺ͷ Web Incubator Community GroupͰ༷ʑͳఏҊ͕࡞੒ɾٞ࿦͞Ε͍ͯΔ 11 https://scrapbox.io/pastak-pub/໘ന WebAPI100 ࿈ൃ Ͱ৭ʑ঺հ͍ͯ͠·͢ ٕҭCAMPΞΧσϛΞ 83
  61. ୅දతͳϏϧυπʔϧ ᶃ • .ts => .js ΁ม׵͢Δπʔϧ • .ts ͸

    JavaScript ϥϯλΠϜͰ௚઀࣮ߦͰ͖ͳ͍ͷͰɺม׵͕ඞཁ • tsc, swc, esbuild ͳͲ 12 • ݹ͍ ECMAScript όʔδϣϯ΁ม׵ (downlevel) ͢Δπʔϧ • ݹ͍ϒϥ΢βͳͲΛαϙʔτ͢ΔͨΊʹඞཁ • tsc, babel, swc, esbuild ͳͲ 12 Node.js Ͱ͸࠷ۙʹͳͬͯม׵ͤͣͱ΋࣮ߦՄೳʹͳΓ·ͨ͠: https://nodejs.org/api/typescript.html ٕҭCAMPΞΧσϛΞ 86
  62. ୅දతͳϏϧυπʔϧ ᶄ • JavaScript ϑΝΠϧΛ݁߹͢Δπʔϧ (bundler) • ϖʔδΞΫηε௚ޙͷωοτϫʔΫϦΫΤετͷ਺ΛݮΒͨ͢Ίʹඞཁ • webpack,

    rollup ͳͲ • CSS ΍ը૾ϑΝΠϧͳͲ΋ bundle Ͱ͖Δ • JavaScript ϑΝΠϧΛѹॖ͢Δπʔϧ (minifier) • ωοτϫʔΫసૹྔΛݮΒͨ͢Ίʹඞཁ • terser ͳͲ ٕҭCAMPΞΧσϛΞ 87
  63. ୅දతͳϏϧυπʔϧ ᶅ • ౷߹తͳϏϧυπʔϧ • ্هͷػೳΛ·ͱΊͯఏڙ͢Δπʔϧ • next build/next dev,

    Vite ͳͲ • ಺෦తʹ͸ swc ΍ terser ͳͲΛ࢖ͬͯΔ • جຊతʹ͸ɺ͜ΕΛ࢖͏ͱྑ͍ ٕҭCAMPΞΧσϛΞ 88
  64. ౷߹తͳϏϧυπʔϧʹඋΘͬͯΔػೳ ࣮͸ଞʹ΋৭ʑͳػೳ͕උΘͬͯ·͢ɻ • Watch Ϗϧυ • ϑΝΠϧͷมߋΛ؂ࢹͯ͠ɺมߋ͕͋ͬͨΒࣗಈͰϦϏϧυ͢Δ • ։ൃαʔόʔ •

    localhost:3000 ͳͲͰ։ൃதͷΞϓϦέʔγϣϯΛ഑৴ͯ͘͠ΕΔ • Hot Module Replacement (HMR) • ϦϏϧυ݁ՌΛϒϥ΢βʹ։͍͍ͯΔϖʔδʹɺϦϩʔυͳ͠Ͱ൓ө͢Δ13 13 ಺෦తʹ͸ɺWebSocket Λ࢖ͬͯϦϏϧυ݁ՌΛϒϥ΢βʹૹ৴ͯ͠ɺϒϥ΢βଆͰͦͷ൓өΛߦͬͯ·͢ɻΑ Γৄ͍͠࢓૊Έ͸ https://qiita.com/haradakunihiko/items/9840f1ea2ffa0ee0874d Λࢀর͍ͯͩ͘͠͞ɻ ٕҭCAMPΞΧσϛΞ 89
  65. Web ϑϨʔϜϫʔΫʹ͍ͭͯ • Web ϑϨʔϜϫʔΫͱݺ͹ΕΔ΋ͷ΋͋Δ • Next.js, Remix, Nuxt.js, Astro,

    ... • ϑϩϯτΤϯυ։ൃΛ͙͢ʹ࢝ΊΒΕΔΑ͏ɺ৭ʑ૊Έࠐ·Ε ͯΔ ٕҭCAMPΞΧσϛΞ 90
  66. Web ϑϨʔϜϫʔΫ͕૊ΈࠐΜͰΔ΋ͷ • Ϗϧυπʔϧͱͦͷਪ঑ઃఆ • ͍͍ײ͡ͷઃఆ͕૊Έࠐ·Εͯͯɺ΄΅ઃఆෆཁͰ࢖͑Δ • ϧʔλʔ • ιϑτφϏήʔγϣϯ΍

    File-based routing ͳͲͷػೳΛఏڙ • αʔόʔαΠυϨϯμϦϯά (SSR) • Node.js αʔόʔ্ͰίϯϙʔωϯτΛϨϯμʔ͔ͯ͠Β HTML Λฦٕ͢ज़ • SEO ΍ॳճදࣔͷߴ଎Խʹد༩͢Δ • ςετϥϯφʔ ٕҭCAMPΞΧσϛΞ 91
  67. ͲΕΛ࢖͑͹ྑ͍͔ ࡞Γ͍ͨ΋ͷͷཁ݅ʹԠͯ͡ద੾ͳ΋ͷΛબͼ·͠ΐ͏ɻ • React ࢖ͬͯ SSR ΋͍ͨ͠ • Next.js Λ࢖͏

    • React ࢖͏͚Ͳ SSR ͸ෆཁͰɺSEO ΋ؾʹ͠ͳ͍ • Vite + React Λ࢖͏ • Node.js ޲͚ϥΠϒϥϦΛ࡞Γ͍ͨ • tsc ͚ͩͰे෼ • .js ΛωοτϫʔΫܦ༝Ͱऔಘ͠ͳ͍ͷͰɺbundler/minifier ͸ෆཁ ͦΕͧΕͷπʔϧͷ໾ׂ΍໨తΛ஌͍ͬͯΕ͹ɺࣗͣͱ෼͔Δ͸ͣͰ͢ɻ ٕҭCAMPΞΧσϛΞ 92
  68. ͓ർΕ͞·Ͱͨ͠ • JavaScript/TypeScript/React ʹ͍ͭͯͬ͟ͱ঺հ͠·ͨ͠ • ͜Ε͚ͩͰ׬ᘳʹཧղͨ͠ʂͱͳΒͳ͍ͱࢥ͍·͕͢... • ։ൃʹೖΔͨΊɾֶͿͨΊͷ଍͕͔Γʹͳͬͨ͸ͣ • JavaScript

    ΍ϑϩϯτΤϯυͷੈք͸ߋʹ޿͕͍ͬͯ·͢ • ϒϥ΢βΛհͯ͠ɺ͜͜·Ͱଟ͘ͷϢʔβͷ໨ʹ৮ΕΔ෼໺͸தʑ͋Γ ·ͤΜ • ੋඇϑϩϯτΤϯυͷੈքΛָ͠ΜͰ͍ͩ͘͞ ٕҭCAMPΞΧσϛΞ 93