ЁЯПл The SchoolтА║ЁЯУМ UIтА║ЁЯз░ рдзрдбрд╛ 07 тАФ Frameworks: рддреНрдпрд╛рдЪ рдХрд▓реНрдкрдирд╛, automate рдХреЗрд▓реЗрд▓реНрдпрд╛
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯз░ рдзрдбрд╛ 07 тАФ Frameworks: рддреНрдпрд╛рдЪ рдХрд▓реНрдкрдирд╛, automate рдХреЗрд▓реЗрд▓реНрдпрд╛

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 07 тАФ рднрд╛рдЧ 2 рд╕реБрд░реВ! ┬╖ рдорд╛рдЧреАрд▓: lesson-06-accessibility ┬╖ рдкреБрдвреАрд▓: lesson-08-design-tokens


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ06, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд React, Vue рдЖрдгрд┐ Svelte рдЪреА рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рд╕рдлрд░: рддреЗ рдХрд╛рдп automate рдХрд░рддрд╛рдд (рдзрдбрд╛ 05 рдордзрд▓реЗ рд╕рдЧрд│реЗ), рддреНрдпрд╛рдВрдЪреА рдХрд┐рдВрдордд рдХрд╛рдп, рдЖрдгрд┐ рддреБрдордЪреНрдпрд╛рдХрдбреЗ рдЖрдзреАрдЪ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рддреАрди рд╕рд╛рдзреНрдпрд╛ files рдХрдзреА рдпреЛрдЧреНрдп рдЙрддреНрддрд░ рдЕрд╕рддрд╛рдд.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рддреБрдореНрд╣реА рдлрд▓рдХ рд╣рд╛рддрд╛рдиреЗ рдмрд╛рдВрдзрд▓рд╛. рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА state рдмрджрд▓рд▓реА рдХреА рддреБрдореНрд╣реА render() рдмреЛрд▓рд╡рд▓реЗрдд, рдЬреНрдпрд╛рдиреЗ рдпрд╛рджреА рдкреБрдиреНрд╣рд╛ рдмрд╛рдВрдзрд▓реА. рдкрд╛рдЪ cards рд╕рд╛рдареА рд╣реЗ рд╕реБрдВрджрд░ рдЪрд╛рд▓рддреЗ. рдкрд╛рдЪрд╢реЗ cards, рд╡реАрд╕ components рдЖрдгрд┐ рддреЗ рдмрджрд▓рдгрд╛рд░реЗ рд╕рд╣рд╛ рд▓реЛрдХ рдЕрд╕рд▓реЗ рдХреА рджреЛрди рдЕрдбрдЪрдгреА рдпреЗрддрд╛рдд: рд╕рдЧрд│реЗ рдкреБрдиреНрд╣рд╛ рдмрд╛рдВрдзрдгреЗ рд╡рд╛рдпрд╛ рдЬрд╛рдгрд╛рд░реЗ рдХрд╛рдо рдЖрд╣реЗ, рдЖрдгрд┐ "render() рдмреЛрд▓рд╡рд╛рдпрд▓рд╛ рд╡рд┐рд╕рд░реВ рдирдХрд╛" рд╣рд╛ рдирд┐рдпрдо рдорд╛рдгрд╕реЗ рд╡рд┐рд╕рд░рддрд╛рдд.

framework ЁЯз░ рдиреЗрдордХреЗ рддреЗрдЪ рдХрд╛рдо рд╣рд╛рддреА рдШреЗрддреЛ: рджрд┐рд▓реЗрд▓реНрдпрд╛ state рд╕рд╛рдареА UI рдХрд╕рд╛ рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡рд╛ рддреЗ рддреБрдореНрд╣реА рдЬрд╛рд╣реАрд░ рдХрд░рддрд╛, рдЖрдгрд┐ рддреЛ DOM рдордзрд▓реЗ рд╕рдЧрд│реНрдпрд╛рдд рдХрдореА рдмрджрд▓ рд╢реЛрдзреВрди рдХрд╛рдврддреЛ тАФ рдЖрдкреЛрдЖрдк, рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА state рдмрджрд▓рд▓реА рдХреА. рдПрд╡рдвреЗрдЪ. рдзрдбрд╛ 05 рдордзреНрдпреЗ рд╢рд┐рдХрд▓реЗрд▓реЗ рдордирд╛рддрд▓реЗ рдЪрд┐рддреНрд░ рдмрджрд▓рдд рдирд╛рд╣реА; рддреНрдпрд╛рд▓рд╛ рдлрдХреНрдд рдПрдХ рдЗрдВрдЬрд┐рди рдорд┐рд│рддреЗ.

рдЕрдВрдЧрдареНрдпрд╛рдЪрд╛ рдирд┐рдпрдо: рддреАрди components state рд╢реЗрдЕрд░ рдХрд░реЗрдкрд░реНрдпрдВрдд vanilla рд╡рд░рдЪ рд░рд╛рд╣рд╛. рдордЧ team рдЖрдгрд┐ ecosystem рдкрд╛рд╣реВрди рдирд┐рд╡рдбрд╛, benchmark рдкрд╛рд╣реВрди рдирд╛рд╣реА.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    ideas["ЁЯза lesson 05: state тЖТ components тЖТ render()"]
    r["тЪЫя╕П React тАФ JSX + hooks + virtual DOM diff"]
    v["ЁЯЯв Vue тАФ templates + reactivity"]
    s["ЁЯзб Svelte тАФ compiles to direct DOM updates"]
    van["ЁЯНж vanilla тАФ you call render() yourself"]
    ideas --> r & v & s & van
    cost["all of them add: a build step, a bundle, an upgrade path, a hiring pool"]

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг "рдХреЛрдгрддрд╛ framework" рд╣рд╛ front-end рдордзрд▓рд╛ рд╕рдЧрд│реНрдпрд╛рдд рдореЛрдареНрдпрд╛ рдЖрд╡рд╛рдЬрд╛рддрд▓рд╛ рдкреНрд░рд╢реНрди рдЖрд╣реЗ рдЖрдгрд┐ рдЬрд╡рд│рдЬрд╡рд│ рдХрдзреАрдЪ рдорд╣рддреНрддреНрд╡рд╛рдЪрд╛ рдирд╕рддреЛ. рдорд╣рддреНрддреНрд╡рд╛рдЪрд╛ рдкреНрд░рд╢реНрди рдЕрд╕рд╛: рддреБрдореНрд╣рд╛рд▓рд╛ state тЖТ view, keys, рдЖрдгрд┐ рддреБрдореНрд╣реА phone рд▓рд╛ рдХрд╛рдп рдкрд╛рдард╡рдд рдЖрд╣рд╛рдд рд╣реЗ рд╕рдордЬрддреЗ рдХрд╛. рдЖрддрд╛ рддреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рдордЬрддреЗ тАФ рдореНрд╣рдгреВрди рддреБрдореНрд╣реА рдЦрд▒реНрдпрд╛ рдХрд╛рд░рдгрд╛рдВрд╕рд╛рдареА framework рдирд┐рд╡рдбреВ рд╢рдХрддрд╛, рдХрд┐рдВрд╡рд╛ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕рд╛рдиреЗ рдирд╛рдХрд╛рд░реВ рд╢рдХрддрд╛.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ тАФ рднрд╛рд╖рд╛рдВрддрд░рд╛рдЪрд╛ рд╕рд░рд╛рд╡)

рдЖрдкрд▓реЗ StudentCard рдЖрдгрд┐ render() framework code рд╡рд░ рдПрдХрд╛рд╕-рдПрдХ рдмрд╕рддрд╛рдд. React рдордзреНрдпреЗ рддреЛрдЪ рдлрд▓рдХ рд╕рд╛рдзрд╛рд░рдг рдЕрд╕рд╛ рджрд┐рд╕рддреЛ:

function StudentCard({ s }) {                 // our StudentCard(s)
  return <li className="card"><strong>{s.name}</strong> <span>class {s.class}</span></li>;
}
function Board() {
  const [students, setStudents] = useState([]);   // our state.students
  const [filter, setFilter] = useState("");       // our state.filter
  useEffect(() => { fetch("/api/students").then(r => r.json()).then(d => setStudents(d.items)); }, []);
  const rows = students.filter(s => !filter || s.class === filter);   // derived, not stored (lesson 05!)
  return <ul className="cards">{rows.map(s => <StudentCard key={s.id} s={s} />)}</ul>;
}

рдХреБрдареЗрд╣реА render() call рдирд╛рд╣реА: setStudents рд╣рд╛рдЪ рддреЛ call рдЖрд╣реЗ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

# 1) on paper (10 min): translate the enrol form into React тАФ which lines are state, which are the component,
#    where does e.preventDefault() go, and what replaces our manual render()?
# 2) count the cost: our board ships ~9 KB of HTML+CSS+JS, uncompressed and unminified.
wc -c ui/index.html ui/styles.css ui/app.js
#    a "hello world" React app ships ~140 KB of framework before your code. Both numbers are fine тАФ know which you are paying.
# 3) the honest test: does your next feature need shared state across three components? If not, stay vanilla.

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

рддреБрдордЪреНрдпрд╛ React рдЖрд░рд╛рдЦрдбреНрдпрд╛рдд app.js рд╕рд╛рд░рдЦреЗрдЪ рдЪрд╛рд░ рднрд╛рдЧ рдЖрд╣реЗрдд (state, component, derived list, fetch рдХрд░рдгрд╛рд░рд╛ effect) рдЖрдгрд┐ рд╣рд╛рддрд╛рдиреЗ repaint рдирд╛рд╣реА. Byte count рджрд╛рдЦрд╡рддреЛ рдХреА рд╕рдВрдкреВрд░реНрдг рдлрд▓рдХ рдХрд╛рд╣реА kilobytes рдЪрд╛ рдЖрд╣реЗ.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

Frameworks рдзрдбрд╛ 05 рдЪреА рдЬрд╛рдЧрд╛ рдШреЗрдд рдирд╛рд╣реАрдд, рддрд░ рддреЛ automate рдХрд░рддрд╛рдд тАФ рдореНрд╣рдгреВрди рддреБрдореНрд╣реА рддреНрдпрд╛рдВрдкреИрдХреА рдХреЛрдгрддрд╛рд╣реА рд╡рд╛рдЪреВ рд╢рдХрддрд╛, рдЖрдгрд┐ рдПрдХрд╣реА рди рдирд┐рд╡рдбрдгреНрдпрд╛рдЪреЗ рд╕рдорд░реНрдерди рдХрд░реВ рд╢рдХрддрд╛.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: framework рдЪреА рдирд┐рд╡рдб team рдордзрд▓реНрдпрд╛ рдмрд╣реБрддреЗрдХ рд▓реЛрдХрд╛рдВрдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЯрд┐рдХрддреЗ. рдЬреНрдпрд╛ teams рдирд╛ рдЦрд╛рд▓рдЪреНрдпрд╛ рдХрд▓реНрдкрдирд╛ рд╕рдордЬрддрд╛рдд рддреНрдпрд╛рдЪ рдЙрддреНрдкрд╛рджрдХ рд░рд╛рд╣рддрд╛рдд, рдХрд╛рд░рдг рддреНрдпрд╛ rewrite рди рдХрд░рддрд╛ upgrade, migrate рдХрд┐рдВрд╡рд╛ рдмрд╛рд╣реЗрд░ рдкрдбреВ рд╢рдХрддрд╛рдд.

тПня╕П рдкреБрдвреЗ

рддреБрдореНрд╣реА рдХрд╕реЗрд╣реА render рдХрд░рд╛, рдлрд▓рдХрд╛рд▓рд╛ рдПрдХрдЪ рд░реВрдк рд╣рд╡реЗ: design systems рдЖрдгрд┐ tokens тАФ рдПрдХрд╛ рдкрддреНрд░рдХрд╛рддреВрди рд░рдВрдЧ, рдЕрдВрддрд░, рдЕрдХреНрд╖рд░реЗ рдЖрдгрд┐ dark mode.

git checkout lesson-08-design-tokens

ЁЯз░ Lesson 07 тАФ Frameworks: the same ideas, automated

ЁЯУН You are here: Lesson 07 of 12 тАФ Part 2 begins! ┬╖ Previous: lesson-06-accessibility ┬╖ Next: lesson-08-design-tokens


ЁЯУж What's in this branch

Lessons 01тАУ06, plus the honest tour of React, Vue and Svelte: what they automate (everything in lesson 05), what they cost, and when the three plain files you already have are the right answer.

ЁЯзТ Explain like I'm 5

You built the board by hand. Every time state changed you called render(), which rebuilt the list. That works beautifully for five cards. For five hundred cards, twenty components and six people editing them, two problems appear: rebuilding everything is wasteful, and "remember to call render()" is a rule humans forget.

A framework ЁЯз░ takes over exactly that: you declare what the UI should look like for a given state, and it works out the smallest set of DOM changes тАФ automatically, every time state changes. That is all. The mental model you learned in lesson 05 does not change; it gets an engine.

The rule of thumb: stay vanilla until three components share state. Then pick by team and ecosystem, not by benchmark.

ЁЯЧ║я╕П Diagram

flowchart LR
    ideas["ЁЯза lesson 05: state тЖТ components тЖТ render()"]
    r["тЪЫя╕П React тАФ JSX + hooks + virtual DOM diff"]
    v["ЁЯЯв Vue тАФ templates + reactivity"]
    s["ЁЯзб Svelte тАФ compiles to direct DOM updates"]
    van["ЁЯНж vanilla тАФ you call render() yourself"]
    ideas --> r & v & s & van
    cost["all of them add: a build step, a bundle, an upgrade path, a hiring pool"]

тЭУ What

ЁЯдФ Why

Because "which framework" is the loudest question in front-end and almost never the important one. The important one is whether you understand state тЖТ view, keys, and what you are shipping to a phone. You now do тАФ so you can pick a framework for real reasons, or decline one with confidence.

ЁЯФз How (in this repo тАФ the translation exercise)

Our StudentCard and render() map one-to-one onto framework code. In React the same board is roughly:

function StudentCard({ s }) {                 // our StudentCard(s)
  return <li className="card"><strong>{s.name}</strong> <span>class {s.class}</span></li>;
}
function Board() {
  const [students, setStudents] = useState([]);   // our state.students
  const [filter, setFilter] = useState("");       // our state.filter
  useEffect(() => { fetch("/api/students").then(r => r.json()).then(d => setStudents(d.items)); }, []);
  const rows = students.filter(s => !filter || s.class === filter);   // derived, not stored (lesson 05!)
  return <ul className="cards">{rows.map(s => <StudentCard key={s.id} s={s} />)}</ul>;
}

No render() call anywhere: setStudents is the call.

ЁЯзк Try it

# 1) on paper (10 min): translate the enrol form into React тАФ which lines are state, which are the component,
#    where does e.preventDefault() go, and what replaces our manual render()?
# 2) count the cost: our board ships ~9 KB of HTML+CSS+JS, uncompressed and unminified.
wc -c ui/index.html ui/styles.css ui/app.js
#    a "hello world" React app ships ~140 KB of framework before your code. Both numbers are fine тАФ know which you are paying.
# 3) the honest test: does your next feature need shared state across three components? If not, stay vanilla.

тЬЕ Verify тАФ what you should see

Your React sketch has the same four pieces as app.js (state, component, derived list, effect that fetches) and no manual repaint. The byte count shows the board is a few kilobytes in total.

ЁЯПБ What you just proved

Frameworks automate lesson 05 rather than replacing it тАФ so you can read any of them, and justify choosing none.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: framework choice outlives most of the team. The teams that stay productive are the ones who understand the ideas underneath, so they can upgrade, migrate or opt out without a rewrite.

тПня╕П Next

However you render it, the board needs one look: design systems and tokens тАФ colours, spacing, type and dark mode from one sheet.

git checkout lesson-08-design-tokens
тЖР PreviousaccessibilityNext тЖТdesign tokens

This page is the lesson's README from the lesson-07-frameworks branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.