Ja has escrit diversos components el return dels quals conté alguna cosa que sembla HTML però que viu dins d'un fitxer JavaScript. Això és JSX, i mereix una lliçó pròpia perquè gairebé tots els entrebancs de les primeres setmanes amb React vénen de donar per fet que JSX és HTML. No ho és: és sintaxi de JavaScript disfressada d'HTML. En aquesta lliçó desmitificaràs JSX veient en què es transforma realment, n'aprendràs les regles exactes i dominaràs la interpolació amb claus, que és el que converteix una targeta de text fix en una targeta que mostra dades reals de CicloUrbano.

Contingut

  1. Què és JSX i en què es transforma
  2. Regla 1: un únic element arrel (i els fragments)
  3. Regla 2: atributs amb noms de JavaScript
  4. Regla 3: totes les etiquetes s'han de tancar
  5. Interpolació amb claus: expressions sí, sentències no
  6. Atributs dinàmics
  7. Estils en línia amb objecte
  8. Comentaris dins de JSX
  9. Què pinta React i què no: null, undefined, false i el cas del 0
  10. Taula comparativa HTML vs JSX

  1. Què és JSX i en què es transforma

JSX (JavaScript XML) és una extensió de sintaxi per a JavaScript. Els navegadors no l'entenen: abans d'arribar al navegador, una eina de construcció (en el nostre cas Vite, mitjançant @vitejs/plugin-react) la tradueix a JavaScript normal.

La millor manera de perdre-li la por és veure la traducció. Aquest component:

function Benvinguda() {
  return (
    <header className="capcalera">
      <h1>CicloUrbano</h1>
      <p>Lloguer de bicicletes per hores</p>
    </header>
  );
}

Es converteix, conceptualment, en això:

function Benvinguda() {
  return React.createElement(
    'header',                                        // 1. tipus d'element
    { className: 'capcalera' },                      // 2. props (atributs)
    React.createElement('h1', null, 'CicloUrbano'),  // 3. fills...
    React.createElement('p', null, 'Lloguer de bicicletes per hores')
  );
}

React.createElement rep sempre tres coses: el tipus d'element, un objecte amb les seves propietats i els seus fills. I retorna un objecte JavaScript senzill, una cosa semblant a:

{
  type: 'header',
  props: {
    className: 'capcalera',
    children: [ /* objectes de h1 i p */ ]
  }
}

D'això es deriven tres conclusions importantíssimes:

  • JSX és sucre sintàctic. Podries escriure React sencer sense JSX, amb createElement a mà. Ningú ho fa perquè és il·legible, però convé saber que no hi ha cap màgia.
  • JSX produeix objectes, no HTML. El que retorna el teu component no és una cadena de text ni un node del DOM: és un objecte lleuger que descriu la interfície. Aquest objecte és la peça que React compara per saber què ha d'actualitzar, tema de la lliçó següent.
  • Un element JSX és un valor de JavaScript. El pots desar en una variable, passar-lo com a argument o retornar-lo des d'una funció:
const capcalera = <h2>Bicicletes disponibles</h2>;
const targetes = [<TargetaBicicleta />, <TargetaBicicleta />];

Nota sobre React 19: des de la «nova transformació de JSX» (React 17 en endavant) el compilador no genera literalment React.createElement, sinó una funció interna _jsx que importa de manera automàtica. Aquest és el motiu pel qual ja no necessites escriure import React from 'react' a cada fitxer, com sí que exigien els tutorials antics. La idea és idèntica; només canvia el detall d'implementació.

  1. Regla 1: un únic element arrel (i els fragments)

Una funció només pot retornar un valor. Com que JSX es tradueix en una crida a createElement, un component només pot retornar un element arrel.

// ERROR: dos elements germans al mateix nivell
function Capcalera() {
  return (
    <h1>CicloUrbano</h1>
    <p>Lloguer per hores</p>
  );
}

Vite ho rebutja amb Adjacent JSX elements must be wrapped in an enclosing tag.

La solució òbvia és embolcallar-ho en un contenidor:

function Capcalera() {
  return (
    <header>
      <h1>CicloUrbano</h1>
      <p>Lloguer per hores</p>
    </header>
  );
}

Però de vegades no vols un contenidor extra: afegiria un div inútil al DOM que pot trencar un grid, un flex o la semàntica d'una taula. Per a això existeixen els fragments, que agrupen sense generar cap etiqueta:

function DadesBicicleta() {
  return (
    <>
      <dt>Model</dt>
      <dd>Urbana Clàssica</dd>
      <dt>Preu</dt>
      <dd>2,50 € / hora</dd>
    </>
  );
}

<>...</> és la sintaxi abreujada del fragment. També existeix la forma llarga, <Fragment>...</Fragment>, necessària únicament quan el fragment ha de portar una key (una cosa que passa en recórrer llistes, a la lliçó 03-03):

import { Fragment } from 'react';

<Fragment key={bicicleta.id}>
  <dt>{bicicleta.model}</dt>
  <dd>{bicicleta.preuHora} €/h</dd>
</Fragment>

Regla pràctica: si el contenidor aporta significat (<article>, <section>, <ul>), fes-lo servir. Si només hi seria per contentar React, fes servir un fragment.

  1. Regla 2: atributs amb noms de JavaScript

A JSX, els atributs són en realitat propietats d'un objecte JavaScript. Això obliga a dos ajustos respecte a l'HTML.

Paraules reservades. class i for són paraules reservades del llenguatge, així que es reanomenen:

<article className="targeta-bicicleta">
  <label htmlFor="model">Model</label>
  <input id="model" />
</article>

camelCase. Els atributs compostos per diverses paraules s'escriuen en camelCase, perquè així es diuen les propietats equivalents al DOM:

HTML JSX
class className
for htmlFor
tabindex tabIndex
onclick onClick
maxlength maxLength
readonly readOnly
autocomplete autoComplete
colspan colSpan
stroke-width (SVG) strokeWidth

Hi ha dues excepcions que convé recordar perquè solen sorprendre: els atributs data-* i aria-* mantenen els guions tal qual, ja que no són propietats del DOM sinó atributs genuïns.

<button
  className="boto-reserva"
  data-bicicleta-id="bici-001"
  aria-label="Reservar Urbana Clàssica"
  onClick={reservar}
>
  Reservar
</button>

Bona notícia: si t'equivoques, React sol avisar-te a la consola amb un missatge molt clar del tipus «Invalid DOM property class. Did you mean className?». Llegeix-los, no els ignoris.

  1. Regla 3: totes les etiquetes s'han de tancar

JSX hereta el rigor d'XML: no existeixen etiquetes obertes. En HTML pots escriure <br> o <img src="..."> i el navegador ho tolera; en JSX és un error de sintaxi.

// ERROR
<img src="/logo-ciclourbano.svg" alt="CicloUrbano">
<br>
<input type="text">

// CORRECTE: autotancament amb barra final
<img src="/logo-ciclourbano.svg" alt="CicloUrbano" />
<br />
<input type="text" />

El mateix s'aplica als teus propis components: <TargetaBicicleta />, no <TargetaBicicleta>. I les etiquetes amb contingut s'han de tancar sempre i en l'ordre correcte; JSX no perdona un <p> sense </p> ni un imbricament creuat.

  1. Interpolació amb claus: expressions sí, sentències no

Aquí hi ha la potència real de JSX. Les claus {} obren una finestra de tornada a JavaScript: el que hi posis a dins s'avalua i el resultat s'insereix a la interfície.

function TargetaBicicleta() {
  const bicicleta = {
    id: 'bici-001',
    model: 'Urbana Clàssica',
    tipus: 'urbana',
    estat: 'disponible',
    preuHora: 2.5
  };
  const estacio = 'Plaça Major';

  return (
    <article className="targeta-bicicleta">
      <h3>{bicicleta.model}</h3>
      <p>Tipus: {bicicleta.tipus}</p>
      <p>Estat: {bicicleta.estat}</p>
      <p>Estació: {estacio}</p>
      <p>{bicicleta.preuHora.toFixed(2)} € / hora</p>
      <p>Preu de 3 hores: {(bicicleta.preuHora * 3).toFixed(2)} €</p>
    </article>
  );
}

export default TargetaBicicleta;

Compara-ho amb la versió de la lliçó anterior: el text ja no està escrit a mà, sinó calculat a partir de dades. És el mateix component, però ara és dinàmic.

Dins de les claus hi cap qualsevol expressió de JavaScript:

<p>{bicicleta.model}</p>                                   {/* accés a propietat */}
<p>{bicicleta.preuHora * 3}</p>                             {/* operació aritmètica */}
<p>{bicicleta.model.toUpperCase()}</p>                      {/* crida a mètode */}
<p>{`${bicicleta.model} — ${bicicleta.tipus}`}</p>           {/* plantilla de cadena */}
<p>{bicicleta.estat === 'disponible' ? 'Lliure' : 'Ocupada'}</p>  {/* operador ternari */}
<p>{new Date().getFullYear()}</p>                           {/* crida a una API */}

La regla que ho governa tot: expressions sí, sentències no. Una expressió produeix un valor; una sentència executa una acció. Com que el contingut de les claus acaba sent un argument d'una crida a funció, ha de produir un valor.

Permès (expressió) No permès (sentència)
bicicleta.model const x = 5;
a + b, a * 3 if (a) { ... }
condicio ? 'sí' : 'no' for (...) { ... }
llista.map(...), llista.filter(...) switch (...) { ... }
funcio(argument) return ...

Això explica per què a React el renderitzat condicional s'escriu amb l'operador ternari o amb &&, i per què les llistes es pinten amb .map() en lloc d'un bucle for: són les versions expressió d'aquestes construccions. Tots dos temes tenen lliçó pròpia: Renderitzat Condicional i Llistes i Claus. Aquí només cal que n'entenguis el perquè.

Si un càlcul és massa llarg per cabre en una expressió llegible, la solució és treure'l abans del return, on sí que pots escriure totes les sentències que vulguis:

function TargetaBicicleta() {
  const bicicleta = { model: 'Elèctrica Pro', estat: 'alquilada', preuHora: 4 };

  // Aquí a dalt estàs en JavaScript normal: if, for, variables, el que sigui
  let etiquetaEstat;
  if (bicicleta.estat === 'disponible') {
    etiquetaEstat = 'Llesta per llogar';
  } else if (bicicleta.estat === 'alquilada') {
    etiquetaEstat = 'En ús ara mateix';
  } else {
    etiquetaEstat = 'En manteniment';
  }

  return (
    <article className="targeta-bicicleta">
      <h3>{bicicleta.model}</h3>
      <p>{etiquetaEstat}</p>
    </article>
  );
}

Aquest patró —calcular a dalt, mostrar a baix— manté el JSX net i és un dels senyals de codi React ben escrit.

  1. Atributs dinàmics

Les claus també funcionen als atributs. La diferència és subtil però fonamental:

<img src="/logo.svg" />        {/* cometes: valor literal, la cadena "/logo.svg" */}
<img src={rutaLogo} />         {/* claus: expressió, el valor de la variable rutaLogo */}

Un error molt comú és barrejar-les: src="{rutaLogo}" passa la cadena literal "{rutaLogo}", no el valor. Cometes o claus, mai totes dues alhora.

Exemple complet aplicat a CicloUrbano, construint classes CSS dinàmiques:

function TargetaBicicleta() {
  const bicicleta = {
    id: 'bici-002',
    model: 'Elèctrica Pro',
    tipus: 'electrica',
    estat: 'alquilada',
    preuHora: 4
  };
  const disponible = bicicleta.estat === 'disponible';

  return (
    <article
      className={`targeta-bicicleta targeta-bicicleta--${bicicleta.tipus}`}
      data-bicicleta-id={bicicleta.id}
    >
      <h3>{bicicleta.model}</h3>
      <span className={`estat estat--${bicicleta.estat}`}>{bicicleta.estat}</span>
      <p>{bicicleta.preuHora.toFixed(2)} € / hora</p>
      <button disabled={!disponible} aria-label={`Reservar ${bicicleta.model}`}>
        Reservar
      </button>
    </article>
  );
}

Detalls a observar:

  • className amb plantilla de cadena. Produeix "targeta-bicicleta targeta-bicicleta--electrica". És el patró habitual per combinar una classe base amb un modificador.
  • disabled={!disponible}. Els atributs booleans reben un booleà de debò, no una cadena. Si el valor és false, React omet l'atribut a l'HTML generat. Compte amb disabled="false": com que qualsevol cadena no buida és true en JavaScript, el botó quedaria deshabilitat!
  • aria-label dinàmic. Els atributs d'accessibilitat es beneficien moltíssim de la interpolació: cada botó descriu exactament la seva bicicleta.
  • data-bicicleta-id conserva els guions, com hem vist.

  1. Estils en línia amb objecte

En HTML, style rep una cadena de text CSS. En JSX rep un objecte de JavaScript:

<p style={{ color: '#12805c', fontWeight: 'bold' }}>Disponible</p>

Aquest doble parell de claus confon tothom la primera vegada, així que separa-les mentalment:

  • Les claus exteriors són la interpolació de JSX: «aquí ve una expressió de JavaScript».
  • Les claus interiors són un objecte literal de JavaScript.

És exactament el mateix que escriure:

const estilsDisponible = { color: '#12805c', fontWeight: 'bold' };

<p style={estilsDisponible}>Disponible</p>

Regles d'aquest objecte:

CSS JSX
background-color: #fff; backgroundColor: '#fff'
font-size: 14px; fontSize: 14 (els píxels s'afegeixen sols) o fontSize: '14px'
border-radius: 8px; borderRadius: 8
margin: 0 auto; margin: '0 auto' (valors compostos, sempre en cadena)
--color-marca: #12805c; '--color-marca': '#12805c' (les variables CSS conserven els guions)

Les propietats van en camelCase i els valors són cadenes, tret dels numèrics de propietats que accepten píxels, on React afegeix px automàticament. Compte amb aquesta comoditat: lineHeight: 2 significa «2 vegades», no «2 píxels», perquè line-height és adimensional.

Exemple aplicat, amb un color d'estat calculat:

function EtiquetaEstat() {
  const estat = 'mantenimiento';

  const colors = {
    disponible: '#12805c',
    alquilada: '#b45309',
    mantenimiento: '#9b1c1c'
  };

  return (
    <span
      style={{
        color: colors[estat],
        border: `1px solid ${colors[estat]}`,
        borderRadius: 4,
        padding: '0.15rem 0.5rem',
        fontSize: 13,
        textTransform: 'uppercase'
      }}
    >
      {estat}
    </span>
  );
}

Quan fer servir estils en línia: només per a valors realment dinàmics que depenen de dades (un color calculat, una amplada de barra de progrés). Per a tota la resta, fulls d'estil: els estils en línia no admeten :hover, ni media queries, ni pseudoelements, i no es guarden en memòria cau. Les estratègies completes d'estilat es veuen a Estils en els Components.

  1. Comentaris dins de JSX

Els comentaris // i /* */ de JavaScript no funcionen dins del JSX: acabarien pintats com a text. Cal embolcallar-los en claus:

function TargetaBicicleta() {
  // Aquest comentari sí que és vàlid: estem en JavaScript normal
  const bicicleta = { model: 'Càrrega Max', preuHora: 5.5 };

  return (
    <article className="targeta-bicicleta">
      {/* Aquest és el comentari vàlid dins de JSX */}
      <h3>{bicicleta.model}</h3>

      {/*
        Els comentaris de diverses línies
        també funcionen així
      */}
      <p>{bicicleta.preuHora.toFixed(2)} € / hora</p>

      {/* <p>Aquesta línia està desactivada temporalment</p> */}
    </article>
  );
}

Als atributs, en canvi, es comenta com en JavaScript, perquè allà ja estàs dins d'una expressió:

<article
  className="targeta-bicicleta"
  // data-test="pendent de decidir"
>

La majoria d'editors fan el correcte automàticament amb Ctrl+/ si tenen suport de JSX.

  1. Què pinta React i què no: null, undefined, false i el cas del 0

React ignora silenciosament certs valors dins de les claus. Saber quins evita sorpreses desagradables.

Valor Es pinta? Resultat en pantalla
'Urbana Clàssica' Sí Urbana Clàssica
2.5 Sí 2.5
0 Sí 0
null No res
undefined No res
true / false No res
['a', 'b'] Sí ab (concatena els elements)
{ model: 'X' } Error Objects are not valid as a React child

Que null, undefined i false no es pintin és una funcionalitat molt útil: permet escriure «pinta això només si es compleix una condició» sense cap estructura especial.

const bicicleta = { model: 'Elèctrica Pro', estat: 'disponible', autonomiaKm: 45 };

<article className="targeta-bicicleta">
  <h3>{bicicleta.model}</h3>
  {/* Si autonomiaKm és undefined, no es pinta res: sense errors ni forats estranys */}
  <p>{bicicleta.autonomiaKm && `Autonomia: ${bicicleta.autonomiaKm} km`}</p>
</article>

I aquí hi ha el parany del 0. L'operador && retorna l'operand de l'esquerra quan aquest és falsy. Si aquest operand és 0, React sí que el pinta, perquè 0 és un número perfectament vàlid:

const estacio = { nom: 'Parc Nord', placesLliures: 0 };

// MALAMENT: quan placesLliures val 0, a la pantalla apareix un "0" solt
<p>{estacio.placesLliures && `${estacio.placesLliures} places lliures`}</p>
// -> pinta: 0

// BÉ: comparació explícita, la condició ja és un booleà
<p>{estacio.placesLliures > 0 && `${estacio.placesLliures} places lliures`}</p>
// -> no pinta res

// TAMBÉ BÉ: ternari, que deixa explícit el cas contrari
<p>{estacio.placesLliures > 0 ? `${estacio.placesLliures} places lliures` : 'Estació plena'}</p>

Aquest «zero fantasma» és una de les errades més reportades pels principiants en React. La regla per evitar-ho: l'esquerra del && ha de ser sempre un booleà, no un número ni una cadena.

Sobre l'error dels objectes: {bicicleta} falla perquè React no sap com pintar un objecte. Has d'accedir a les seves propietats ({bicicleta.model}) o, si estàs depurant, convertir-lo en text:

<pre>{JSON.stringify(bicicleta, null, 2)}</pre>

  1. Taula comparativa HTML vs JSX

Aspecte HTML JSX
Classe CSS class="targeta" className="targeta"
Etiqueta de formulari for="model" htmlFor="model"
Esdeveniments onclick="reservar()" onClick={reservar} (referència, sense parèntesis)
Atributs compostos tabindex, maxlength tabIndex, maxLength
data-* i aria-* data-id, aria-label Igual, amb guions
Etiquetes buides <br>, <img src="..."> <br />, <img src="..." />
Estil en línia style="color: red" style={{ color: 'red' }}
Valors dinàmics No existeixen {expressio}
Comentaris <!-- ... --> {/* ... */}
Element arrel Diversos permesos Un de sol (o un fragment <>...</>)
Booleans disabled disabled={true} o simplement disabled
Majúscules Irrellevants Determinen si és etiqueta HTML o component

Errors Comuns i Consells

  • Escriure class en lloc de className. L'avís apareix a la consola i els estils no s'apliquen. És tan freqüent que convé automatitzar-ho: amb ESLint ben configurat t'ho marca en escriure.
  • Barrejar cometes i claus: src="{ruta}". Passa la cadena literal. O cometes per a valors fixos, o claus per a expressions.
  • Intentar ficar un if o un for dins de les claus. Són sentències. Treu-los abans del return o fes servir els seus equivalents en forma d'expressió (? :, &&, .map()).
  • Oblidar l'autotancament a <br>, <img>, <input> o <hr>. Error de sintaxi immediat; el missatge de Vite assenyala la línia amb precisió.
  • El «zero fantasma» amb &&. Repeteix-t'ho fins que se't quedi: l'esquerra del && ha de ser un booleà. placesLliures > 0 && ..., mai placesLliures && ....
  • Pintar un objecte: {bicicleta} en lloc de {bicicleta.model}. El missatge Objects are not valid as a React child és literal i et diu exactament què passa.
  • Un sol parell de claus a style. style={{ color: 'red' }} en porta dos: interpolació més objecte.
  • Consell: quan dubtis de què fa un JSX complicat, tradueix-lo mentalment a createElement. Si la traducció no té sentit com a crida a funció, el JSX tampoc no en tindrà.
  • Consell: si el JSX d'un component ocupa més d'una pantalla, no és un problema de JSX sinó de disseny: segurament aquest component estigui fent massa coses i s'hagi de dividir. Ho treballaràs al Mòdul 2.

Exercicis

Exercici 1

Tradueix a JSX correcte el següent HTML d'una targeta d'estació de CicloUrbano. Ha de ser un component TargetaEstacio complet, a punt per fer servir, amb les tres correccions de sintaxi que calen.

<div class="targeta-estacio" style="border-left: 4px solid #12805c">
  <h3>Estació Central</h3>
  <p>Barri Eixample</p>
  <hr>
  <label for="places">Places totals</label>
  <input id="places" type="number" value="30" readonly>
</div>

Exercici 2

Escriu un component ResumReserva que, a partir d'aquestes constants declarades dins del component, mostri el model, les hores, el preu total amb dos decimals i un avís només quan la reserva superi les 4 hores. Tot ha de sortir d'expressions interpolades, sense text fix duplicat.

const bicicleta = { model: 'Elèctrica Pro', preuHora: 4 };
const reserva = { usuari: 'Ana Ribera', hores: 6, estat: 'activa' };

Exercici 3

El component següent té una errada visual: quan placesLliures val 0, apareix un 0 solt en pantalla en lloc de no mostrar-se res. Explica exactament per què passa i proposa dues solucions diferents.

function DisponibilitatEstacio() {
  const estacio = { nom: 'Plaça Major', placesLliures: 0 };

  return (
    <div>
      <h3>{estacio.nom}</h3>
      {estacio.placesLliures && <p>Queden {estacio.placesLliures} places</p>}
    </div>
  );
}

Solucions

Solució 1.

// src/components/TargetaEstacio.jsx
function TargetaEstacio() {
  return (
    <div className="targeta-estacio" style={{ borderLeft: '4px solid #12805c' }}>
      <h3>Estació Central</h3>
      <p>Barri Eixample</p>
      <hr />
      <label htmlFor="places">Places totals</label>
      <input id="places" type="number" value="30" readOnly />
    </div>
  );
}

export default TargetaEstacio;

Les correccions: class → className; l'style com a cadena → objecte amb borderLeft en camelCase i el valor compost entre cometes; <hr> → <hr /> i l'<input> autotancat; for → htmlFor; readonly → readOnly.

Un detall extra: React avisarà a la consola que un input amb value fix i sense gestor de canvis és de només lectura. Aquí és intencionat, i per això porta readOnly; els camps editables s'estudien a Formularis i Components Controlats.

Solució 2.

// src/components/ResumReserva.jsx
function ResumReserva() {
  const bicicleta = { model: 'Elèctrica Pro', preuHora: 4 };
  const reserva = { usuari: 'Ana Ribera', hores: 6, estat: 'activa' };

  // Càlcul fora del JSX: més llegible i reutilitzable
  const total = bicicleta.preuHora * reserva.hores;

  return (
    <article className="resum-reserva">
      <h3>Reserva de {reserva.usuari}</h3>
      <p>
        {bicicleta.model} · {reserva.hores} hores
      </p>
      <p>
        Total: <strong>{total.toFixed(2)} €</strong>
      </p>
      {reserva.hores > 4 && <p>Reserva de llarga durada: recorda tornar-la a la seva estació.</p>}
    </article>
  );
}

export default ResumReserva;

Amb aquestes dades mostra «Total: 24.00 €» i l'avís, perquè 6 és més gran que 4. Fixa't que la condició del && és una comparació, així que ja és un booleà: no hi ha risc de zero fantasma.

Solució 3.

Per què passa: l'operador && avalua l'operand esquerre; si és falsy, retorna aquest mateix valor en lloc d'un booleà. Com que placesLliures val 0, l'expressió completa retorna 0. I 0 és un número vàlid per a React, que el pinta tal qual. Només null, undefined, true i false s'ometen silenciosament.

Solució A — convertir la condició en un booleà explícit:

{estacio.placesLliures > 0 && <p>Queden {estacio.placesLliures} places</p>}

Solució B — utilitzar un ternari, que a més cobreix el cas contrari:

{estacio.placesLliures > 0 ? (
  <p>Queden {estacio.placesLliures} places</p>
) : (
  <p>Estació plena</p>
)}

Una tercera via, una mica menys llegible però també vàlida, és forçar el booleà amb doble negació: {!!estacio.placesLliures && ...}. Prefereix sempre la comparació explícita: comunica millor la intenció.

Conclusió

JSX no és HTML: és sintaxi que es transforma en crides a funció que produeixen objectes JavaScript que descriuen la interfície. D'aquesta naturalesa se'n deriven totes les seves regles: un únic element arrel (o un fragment <>...</>), atributs amb noms de propietat del DOM (className, htmlFor, camelCase), tancament obligatori de totes les etiquetes, i claus {} per interpolar expressions —mai sentències—. Ja saps construir atributs dinàmics, aplicar estils en línia amb objecte, comentar amb {/* */} i evitar el parany del 0 amb &&.

Amb això ja pots descriure qualsevol interfície. Queda una pregunta essencial per respondre: què fa React exactament amb aquests objectes que retornen els teus components? Com passa d'una descripció en memòria a píxels a la pantalla, i com aconsegueix actualitzar-la sense repintar-ho tot? Això és el que veuràs a Com Renderitza React: Virtual DOM i Reconciliació, la lliçó que tanca aquest primer mòdul.

Curs de React

Mòdul 1: Introducció a React

Mòdul 2: Components de React

Mòdul 3: Treballar amb Esdeveniments

Mòdul 4: Conceptes Avançats de Components

Mòdul 5: Hooks de React

Mòdul 6: Enrutament a React

Mòdul 7: Gestió de l'Estat

Mòdul 8: Optimització del Rendiment

Mòdul 9: Proves a React

Mòdul 10: Temes Avançats

Mòdul 11: Projecte: Construir una Aplicació Completa

© Copyright 2026. Tots els drets reservats