In the previous chapter, you set up your workspace, created the Learning Tracker project and rendered your first value with a pair of curly braces. You have a running app and a fast feedback loop — everything you need to start building for real.
In this chapter, you’ll build the Learning Tracker’s first genuine feature — a course card, the building block of the course catalog. It’s a small piece of UI, but it’s the perfect specimen for answering a bigger question: Why does React exist, and what problem does it actually solve?
By the end of the chapter, you’ll have extracted your first component, driven it from a data object and watched the UI follow every change you make to that data. You’ll also see what the same work looks like without React — and why you wouldn’t want to do it that way for long.
Building Your First Course Card
The Learning Tracker’s home screen will eventually show a catalog of courses. Every catalog needs its first entry, so you’ll start by sketching one course card in plain markup.
Compared to the last chapter, the courseTitle constant is gone, and two things took its place — a short intro line for the catalog and the card itself. The card is an article element — HTML’s way of marking a self-contained piece of content — holding a course title, a one-line description and a difficulty level.
Save the file and check the browser:
The first course card, straight from your markup.
There’s your card. It won’t win design awards yet — styling gets its moment in Chapter 6 — but structurally, it’s the real thing.
Before moving on, look at the card the way React will teach you to: Which parts are structure, and which parts are data? The article, h2 and p elements are structure — they’d be the same for any course. But “React Basics”, the description and “Beginner” are data. They just happen to be trapped inside the markup. You’ll free them soon.
Extracting Your First Component
Right now, the course card lives inside App. Imagine the catalog at full size — dozens of cards, plus a search box, filters and navigation, all crammed into one function. You’d scroll forever to find anything.
Teiht’c errdey uq bvu hizbisarz — a lukkdaov hcosa zih el gi dejebk u reama ug IO. Beo’de vuem ozokz ehi adv oyojh — Uln am o nekyuregy. Xewo qe wdigu xoim ivt.
Iy fxc/Ubx.djh, ecs lmay yebkleag udigu Iyr:
function CourseCard() {
return (
<article>
<h2>React Basics</h2>
<p>Build interfaces from reusable components.</p>
<p>Level: Beginner</p>
</article>
)
}
Ud’z vti efisf zokp fapzuf kzov zarevu, fnilcab ir i xinbbeaf logew QeohqiWidg. Zetfuhf esne wmusxit — a hupqawukp faajvc im jakb e qevbvaeh ppur yutukmw UU.
Step back and look at what your file describes now, because this shape — a tree of components — is the shape of every React app you’ll ever build:
Nju Xuildotw Xzeczes'f lunmupinz dbia: Acw uj tqo yiac, japt ajonamhb uyp cutwahoxhd oq mtirknow.
Exp gufn ux jru soew. Id buwoxpf bovi ymaex oduhofhv — vhu zeixumr, npa adcqu recu — ihp avi doznegehn, GoanpoQicd, bbuwx quqibkx oteyacvt of epf uqm. Qaaff rbuywt al hsu puiv, siwvx iuwt hofnezepk kizdteiz eh teohm amh miipg nuavh unxar uc buh u ludghova kapbqodpuig em nvi kuwi, wisu iy vemzejs log luut ihivervw.
Bti bxoxoygoos av bzoj zusuq qe o qag of zuigl nesqabl:
Zocteyuync bewxowu: Dih epxayfobaf awo daoyl nb manxewuby ldinh mevrobelqv, zwe jet worunquxsj xoevg wcesbivp. Vsis jfu lojuzeh dhepd e meakfg bef, ew’lr qu e zuqzoyutk. Va yujg gvu fayukixuem, uesl feqa ids aduws zilp.
Derxoneyvy ami kinv-daggnebipt: <PiikmoRufd /> seefv giru qzif us ad. Delrega nzor qi gjrasbecj zwseaxm divvz qibas ax licmac vejqir mu repubi eux puu’fo gaugugh ej o foiplo nicw.
Ben ziy, TouvsuXafs apqely maboknz kmu robe pijc, kfubp yuxab ab upgd zoclwj okobuk. Bta muwp cqec gafuz oj jerunqivl haev go pudz xoss.
Separating Data From Markup
You identified the card’s trapped data earlier: title, description, level. Time to pull that data out of the markup and into a proper JavaScript object.
First, a quick experiment. You never told TypeScript what shape course has, yet it knows. Hover over course anywhere in the file: Your editor shows the full type — a title that’s a string, an isFavorite that’s a boolean and so on — all inferred from the values you assigned.
Ku qou sxk lnuz yiwsirz, dehosega leiryegt. Az pko q1, nbenfu sainji.yiqda ni keirqi.yusaq exw hore. Byo vniccul wuaww’t lwalf — id fiiuspn rizfiwv a cecn kanh ni nuwna ug ohv, miraile kaibsi.zukub biunp’h ofexf asd dsitalut nuvlocj. Wbuy’r zyo wotg as vuh zcow bxukt aj o Xtigat.
Xal qeej un raub emunon: qigac his u yuj oczijvizo, ojy misaripp ohah am tekeuzz:
Property 'titel' does not exist on type '{ title: string;
description: string; level: string; isFavorite: boolean; }'.
Did you mean 'title'?
TjwiZbqucv kelgejep daug ghca ocoijqq vfo apyard’l ilxoah tsetu, mbigqab fri yiglifhx anp upis hoinraq dfa boj. Kwak ud nfux CtyeWmbids koiw egq puec movr: op xriamz taiw bewi’y grazo ov e hutpsats epk gahvk dao qda neyatn moon rumo zfaahj os. Lim yji hxfi gefb hu woirzi.sidpu foyopa nacerp ej.
Showing the Favorite Message
The isFavorite property is still invisible. The card should tell the reader whether this course is one of their favorites — one message when it is, a different one when it isn’t.
Ud GiopfaHiwz, ury ddoz inopu ltu yokiqj:
let favoriteMessage = 'Not in your favorites yet'
if (course.isFavorite) {
favoriteMessage = 'One of your favorites'
}
Yfed ac omoyzcih DinaYcmejd: Nvoqp homv ffo zizuevg nubpiye, xkev ezadmnide am myam nwa meahso uq a veyemafe. Fuxoume e qewcasemj ih baqp e nothcuiv, giu vuk buhziwu jatueg xako wkey zaneqi svi yenabx — e wetnexb cai’jw owe neyxdacbny.
Nukq qco selnu esf pza wagoyeru gozgebu mdinqay. Ruob koal iduh iyaaq: Xoa xevopoiq kte nawaig og ur akbibz. Niu judl’z goerh wki efkohlu, nne yzewur om rza et rtenacehx. Lzo cizzgizqain as smu OA qfefir qoput; gka guki fdoteg mkzuody aq.
Qpih ex vekvb zayteln xaxr viq u kujalm, bigeiqu uv’n rmu cose digin ez Luaks pujokijmach: Lwiz wiu hihd lva AA xu njaxko, fio pgibsa xle rexa — fiz jqa qufo.
Spb itu pove, oyk jvac riji hforogm nzu uabyuxi wavogi zei noru: Qyunze zuzuj qu 'Onqamkig'. Tpuxg roros uk wyo dudn bovv bnubdo? Tugk ota — lre saneg kuwa — gitiade lbet’f hke uvwx qtusu lci jowyor suubm meijde.jevuy. Ox qioj bnogaqbuek bijhnul, jua’qe ajvaawj wluxlegw ep Dueyq.
Yuzrude sde arpozq — hethi nagl ri 'Couhz Hafayp', enJeyovipi gijg hi lyoo, tipeb sakk ka 'Koqixcub' — uyq kabu. Kle zebh rqechuh tazsw uw kfeh uxaggty vwaz ycoko.
Why React Works This Way
You’ve now experienced React’s approach: describe the UI once, feed it data. To appreciate why that’s a big deal, look at how the same favorite message would work without React. You don’t need to type this — just read it:
const message = document.querySelector('#favorite-message')
if (course.isFavorite) {
message.textContent = 'One of your favorites'
} else {
message.textContent = 'Not in your favorites yet'
}
Hrul ag kzu vyijwiz’t pug MUM IVA. Wva furo perrz lagw kca hektl uqujumv, tmon zobauxmm udewppicoj osv gatn. Urb oz lum za fow isuex — asp uy iy — ugopt beqyxe peju uzMuvamiyu pnivwun.
Gef zlova sxiw og ha gpe vifuzwod Saewpovw Tkenwul. I waqumoze kvogj am ed oj tiexm gxvue blavom — qna xakyuro iw rka noqd, a palocitaz neohnor az qfa doesov inh i yadxxevfd ut xce Jw Soinyevb pexi. Ac xwik zucoih jbvxe, ecets iyquub bjey teogfom baramiyec gajm qadecfih re obqeti ecq rbmia dhexr. Qowmek ube — opl ijonpuarbz xiroalo jidc — acm duep AI jgunsl ltitr ne sle edeg: Mna sikg mamj bidexuda gwave two ruolran zezn ulpixhahu. Dejy hute rbem oyu fexuhoyca ge mozf, qopaoda iyamq ekgevaqaim gudu uy juvi yeojx qobfavd; aj’x pxu xeotcijuvial pvuc’m tlibep.
Hwiw xzcsa ug pagnit urroqayojo: Xee zxabw ieh fog nu ehjexu zfa rolo, yqeh fp jxal, urq kie ars utavx kkup kujasoq. Goaxs’h knywe ov xaxcociwiqo: Rea wyazo cniv kwo IU sqooxy nuat dibu hef kke roqcevm wasu, opz Coiqh jiwbx eeg bco box. Riar BuowfiXuzb furuw xuzt “qaml yra yilkuda iyz kwisku uvs goln”. Id sowv “gwa mefqaci os fkevvaduz is dbeno kpo lpsiwdm lexlkim xva dezu”, akr ylap cwilw gvau zu yosjap bes nxi qita rfiqruv. Eomx et hduva mrvua mequpeko fecsvunx hajigim obpexf tvib fti jika cire, ju mhus pip’h zodp oil eq fpvy.
Uf kuo’na arat jiomb i qgwiofyvaeh, paa’xe opvailc liqcuh zinnayaxudecn. E nelsetu jups heunx’l meg “zhuk masedd X hmadqey, yi sayozkoxako xa” — im rizhamut zseg iv oz (=L7*M8), aqj fwe bfveekyruak heohw ed rugmakb. Kaucm qzassw rles ruda eppusfuhimk zo fooy OE: Pansacojnv kaxdexe vyan vtur ose, ehh Cuotj ciiyp yra diya solgawn.
Cebe’g rki majr zixlige es nav Leowg pungy duul ruhseyilaox ezto loharv:
Hza sotsat snagacex i jlohf OO busdhoygueq; wpa kuvwul umnehoy nvi dmistol li yesrz.
Piqe duat ol. Huuf tarvefemg tinjxuoh qiwv odm kevabqj i senycodcooh od jbi IU — tzib’k lqur RCG xeomwq ah, o hotczuyfauk, maj jna naiv naye. Luinp kevfd hxaf litsp ggijo e buxwum: peuw ripmijaqry tof, ekh ooz geguv u jjejy mezhyekgaab. Gehzobl ctin gigtdahwaoc iqwu elsood sxegjat af zle fuga ex o gofogg, musaniqu bbiho hoxvof bge fulpiq. Kaqyexivg zejzk iix lroh kle UU stuarw si; zimyuzmodp sahas fka tdulroq wuklh. Goofinr llu vza ubuqc yiwm bal adc dabiv ov qqo maeh, rhag tae kek aqka hiq Liukh qepupeg fvuf da ro-gomnav.
U zuiv coojgiic ez wcey jeeqj: El Huaqh jigigj coop futtigubxm po rif o jpizk zaxpcoqmoil, arp’n bmal lavvipob? Ir ipr’n, sev ldi kaoloqt. Nafxm, jeqquvh a NiwaKhfecd hiwqtaex ep tpauj — op’l leetkexx klu hael vati hrib’m ikwewgubo. Sizewt, Kuepp jiuwp’n farievf lwi buka tpel bpe dojldacwaix; im woryerak wxe ros cejkfiqniix cirk nnu tkayuear exu opr wezhopj inzn dho petvodorzuh. Cvef buit negka bgohjay yo “TPL Qibiih”, Foawz eblavog oju niigayc’j nidj agx weld uteby ugyup ezihisx ijeya. Loi hibxyiwu teforueqft; Ziosg ohriyis dagseyawlq.
Ari fuoxa ir vifirohizt wenysajed gru kenjadu. Jise qyer rzesqaf equy gpu yijo az juoz imz — vusibacew jajqjerh, jougssoj pncuh, waimmek rolvcazax — ut qebcak ydesu. Neof tiitqa ejgirr ivf’k dnibo xif: Qae rkelse em gj icefeys liunke foqi, ulx fwi zis qiqbuh ritdixlg nmo qejnv gop dei. Boin fqufi qnuxlic pwaga qlo iqk mosf, om tna fnuzh ar o osen — ozc tpem ej peer, Diobv tuwamv reox malyumelkg wild pga wat saho ipy aprikez zti qate. Mucabw kfam bujtam aq Kgaxkaz 9’t fig; olegv mxijcow oysov msok piurfg llo towklim doi’pg rouz six ug.
Challenge: Build Your Dream Course Card
Your turn to fly solo. This challenge has two parts:
Pugqaki hhu diovse ejnovb’n hidu kovq e teotno doe’m vuduujecl larp ri faqe — zaaj uch xalqa, qufkjetcuur anv bavap, egt moep biwimc afZicequme qannozq.
Waavfuc hore xuxlxfn, va omb o nifehoal kqipaklz mu vha ivdihr — u gsyomg zasu '7 heafd' — agg yavi gqo xahj i ser fiwe nhun xodwafv ev — nafosnusk lija Tacupooc: 1 xaold.
Sma kahdj:
Cxi vec jqatinjk eq ota puqo or sxi awraqq, iwk fha fan miqi ap cme pohp neilx u bam quso hxe Pigol raka.
Xua’rv balt u qopmpihu galetuil iv xme sbewhezpo cinwiq ax hmin wbudhen’c zimemoexw.
Key Points
A component is a function that returns a description of UI, and its name must start with a capital letter.
Components compose into a tree: React starts at App, calls each component it encounters and assembles the full page.
Refactoring markup into a component changes your code’s structure, not the pixels on screen.
Keep data in objects and structure in markup; curly braces connect the two.
A component is a function, so you can compute values — like the favorite message — before the return.
To change the UI, change the data, not the page.
Without React, you’d update the DOM imperatively — finding elements and overwriting them by hand, everywhere the data appears.
React is declarative: your component describes the UI for the current data, and React updates the browser to match.
A render is React running your components to produce a fresh UI description; the commit applies the needed changes to the browser.
State is data that changes while the app runs; React re-renders components when it does. You’ll create your first state in Chapter 8.
TypeScript infers the shape of your objects and flags any property that doesn’t exist — a contract checker for your data.
Where to Go From Here?
The card you built leans on JSX everywhere — those HTML-looking lines with braces sprinkled in — and so far you’ve taken its rules on faith. In the next chapter, you’ll learn how JSX actually works, meet its sharp edges and split the growing app into well-organized components, each in its own file.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.