1"use strict";(globalThis.webpackChunkmotore_temp=globalThis.webpackChunkmotore_temp||[]).push([[1082],{1470:(e,n,a)=>{a.d(n,{A:()=>C});var i=a(6540),o=a(4164),r=a(7559),t=a(3104),l=a(6347),s=a(205),c=a(7485),d=a(1682),u=a(679);function p(e){return i.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function m(e){const{values:n,children:a}=e;return(0,i.useMemo)(()=>{const e=n??function(e){return p(e).map(({props:{value:e,label:n,attributes:a,default:i}})=>({value:e,label:n,attributes:a,default:i}))}(a);return function(e){const n=(0,d.XI)(e,(e,n)=>e.value===n.value);if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[n,a])}function h({value:e,tabValues:n}){return n.some(n=>n.value===e)}function g({queryString:e=!1,groupId:n}){const a=(0,l.W6)(),o=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,c.aZ)(o),(0,i.useCallback)(e=>{if(!o)return;const n=new URLSearchParams(a.location.search);n.set(o,e),a.replace({...a.location,search:n.toString()})},[o,a])]}function v(e){const{defaultValue:n,queryString:a=!1,groupId:o}=e,r=m(e),[t,l]=(0,i.useState)(()=>function({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!h({value:e,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const a=n.find(e=>e.default)??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:r})),[c,d]=g({queryString:a,groupId:o}),[p,v]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[a,o]=(0,u.Dv)(n);return[a,(0,i.useCallback)(e=>{n&&o.set(e)},[n,o])]}({groupId:o}),f=(()=>{const e=c??p;return h({value:e,tabValues:r})?e:null})();(0,s.A)(()=>{f&&l(f)},[f]);return{selectedValue:t,selectValue:(0,i.useCallback)(e=>{if(!h({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),v(e)},[d,v,r]),tabValues:r}}var f=a(2303);const x={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var j=a(4848);function b({className:e,block:n,selectedValue:a,selectValue:i,tabValues:r}){const l=[],{blockElementScrollPositionUntilNextRender:s}=(0,t.a_)(),c=e=>{const n=e.currentTarget,o=l.indexOf(n),t=r[o].value;t!==a&&(s(n),i(t))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const a=l.indexOf(e.currentTarget)+1;n=l[a]??l[0];break}case"ArrowLeft":{const a=l.indexOf(e.currentTarget)-1;n=l[a]??l[l.length-1];break}}n?.focus()};return(0,j.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.A)("tabs",{"tabs--block":n},e),children:r.map(({value:e,label:n,attributes:i})=>(0,j.jsx)("li",{role:"tab",tabIndex:a===e?0:-1,"aria-selected":a===e,ref:e=>{l.push(e)},onKeyDown:d,onClick:c,...i,className:(0,o.A)("tabs__item",x.tabItem,i?.className,{"tabs__item--active":a===e}),children:n??e},e))})}function y({lazy:e,children:n,selectedValue:a}){const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){const e=r.find(e=>e.props.value===a);return e?(0,i.cloneElement)(e,{className:(0,o.A)("margin-top--md",e.props.className)}):null}return(0,j.jsx)("div",{className:"margin-top--md",children:r.map((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==a}))})}function I(e){const n=v(e);return(0,j.jsxs)("div",{className:(0,o.A)(r.G.tabs.container,"tabs-container",x.tabList),
1children:[(0,j.jsx)(b,{...n,...e}),(0,j.jsx)(y,{...n,...e})]})}function C(e){const n=(0,f.A)();return(0,j.jsx)(I,{...e,children:p(e.children)},String(n))}},2162:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>u});const i=JSON.parse('{"id":"path/react/profile-card/README","title":"Profile Card","description":"Scritto il 24 gennaio del 2026","source":"@site/i18n/it/docusaurus-plugin-content-docs/current/02-path/react/profile-card/README.mdx","sourceDirName":"02-path/react/profile-card","slug":"/path/react/profile-card/","permalink":"/it/docs/path/react/profile-card/","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"sidebar_position":3,"sidebar_label":"Card Profilo","title":"Profile Card"},"sidebar":"tutorialSidebar","previous":{"title":"Footer","permalink":"/it/docs/path/react/footer/"},"next":{"title":"Mood Board","permalink":"/it/docs/path/react/mood-board/"}}');var o=a(4848),r=a(8453),t=a(1470),l=a(9365);const s={sidebar_position:3,sidebar_label:"Card Profilo",title:"Profile Card"},c="Card Profilo",d={},u=[{value:"Il Progetto",id:"il-progetto",level:2},{value:"Codice Sorgente",id:"codice-sorgente",level:2},{value:"Cosa Ho Imparato nella Teoria",id:"cosa-ho-imparato-nella-teoria",level:2},{value:"La Maschera del JSX",id:"la-maschera-del-jsx",level:3},{value:"I Componenti come Funzioni Pure",id:"i-componenti-come-funzioni-pure",level:3},{value:"La Teoria dell'Identit\xe0 (Keys)",id:"la-teoria-dellidentit\xe0-keys",level:3},{value:"crypto.randomUUID() - L\u2019arma ideale per gli ID",id:"cryptorandomuuid---larma-ideale-per-gli-id",level:3},{value:"Profile Card",id:"profile-card",level:2},{value:"Cosa Ho Imparato",id:"cosa-ho-imparato",level:2}];function p(e){const n={br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("p",{className:"article-meta",children:(0,o.jsx)("time",{dateTime:"2026-01-24",children:"Scritto il 24 gennaio del 2026"})}),"\n",(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"card-profilo",children:"Card Profilo"})}),"\n",(0,o.jsx)("img",{src:a(3086).A,alt:"Anteprima Profile Card Project - Tre Card Profilo (Mark, Tiffany, Doug)",loading:"lazy",decoding:"async",width:"1904",height:"946",style:{width:"100%",height:"auto",borderRadius:"10px"}}),"\n",(0,o.jsx)(n.h2,{id:"il-progetto",children:"Il Progetto"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Card Profilo"})," \xe8 il mio primo progetto React data-driven, dove ho applicato i concetti di Props, Rendering Condizionale e Liste per trasformare dati statici in componenti dinamici."]}),"\n",(0,o.jsx)(n.h2,{id:"codice-sorgente",children:"Codice Sorgente"}),"\n",(0,o.jsxs)(t.A,{children:[(0,o.jsx)(l.A,{value:"js",label:"index.jsx",default:!0,children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:'export function Card({ name, title, bio }) {\n return (\n <div className="card">\n <h2>{name}</h2>\n <p className="card-title">{title}</p>\n <p>{bio}</p>\n </div>\n )\n}\n\nexport function App() {\n const profiles = [\n {\n id: 1,\n name: "Mark",\n title: "Frontend developer",\n bio: "I like to work with different frontend technologies and play video games."\n },\n {\n id: 2,\n name: "Tiffany",\n title: "Engineering manager",\n bio: "I have worked in tech for 15 years and love to help people grow in this industry."\n },\n {\n id: 3,\n name: "Doug",\n title: "Backend developer",\n bio: "I have been a software developer for over 20 years and I love working with Go and Rust."\n }\n ];\n return (\n <div className="flex-container">\n {profiles.map((profile) => (\n <Card\n key={profile.id}\n name={profile.name}\n title={profile.title}\n bio={profile.bio}\n />\n ))}\n </div>\n );\n}\n'})})}),(0,o.jsx)(l.A,{value:"css",label:"styles.css",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-css",children:":root {\n --dark-grey: #1b1b32;\n --light-grey: #f5f6f7;\n --dark-orange: #f89808;\n}\n\nbody {\n background-color: var(--dark-grey);\n}\n\n.flex-container {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.card {\n border: 5px solid var(--dark-orange);\n border-radius: 10px;\n width: 100%;\n padding: 20px;\n margin: 10px 0;\n background-color: var(--light-grey);\n}\n\n.card-title {\n border-bottom: 4px solid var(--dark-orange);\n width: fit-content;\n}\n\n@media (min-width: 768px) {\n .card {\n width: 300px;\n }\n}\n"})})}),(0,o.jsx)(l.A,{value:"html",label:"index.html",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-html",children:'<!doctype html>\n<html>\n <head>\n <meta charset="UTF-8" />\n <title>Reusable Card component</title>\n <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.js"><\/script>\n <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.js"><\/script>\n\n <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.3/babel.min.js"><\/script>\n <script\n data-plugins="transform-modules-umd"\n type="text/babel"\n src="index.jsx"\n ><\/script>\n <link rel="stylesheet" href="./styles.css" />\n </head>\n <body>\n <div id="root"></div>\n <script\n data-plugins="transform-modules-umd"\n type="text/babel"\n data-presets="react"\n data-type="module"\n >\n import { App } from \'./index.jsx\';\n ReactDOM.createRoot(document.getElementById(\'root\')).render(\n <App />\n );\n <\/script>\n </body>\n</html>\n'})})})]}),"\n",(0,o.jsx)(n.h2,{id:"cosa-ho-imparato-nella-teoria",children:"Cosa Ho Imparato nella Teoria"}),"\n",(0,o.jsx)(n.p,{children:"Prima di arrivare a questo progetto c'\xe8 stata la teoria sui Dati, estremamente interessante. Ecco i concetti che voglio tenermi stretti."}),"\n",(0,o.jsx)(n.h3,{id:"la-maschera-del-jsx",children:"La Maschera del JSX"}),"\n",(0,o.jsxs)(n.p,{children:["Nei progetti precedenti avevo capito che React fosse zucchero sintattico, ma non avevo compreso quanto.\nIn sostanza, sotto il
1cofano \xe8 tutto ",(0,o.jsx)(n.code,{children:"React.createElement"}),", quindi oggetti JavaScript puri. Le ",(0,o.jsxs)(n.strong,{children:["parentesi graffe ",(0,o.jsx)(n.code,{children:"{ }"})]}),' non sono "sintassi React speciale", sono una sorta di \u201cportale\u201d che ti riporta nel mondo JavaScript. Fuori dalle graffe sei in modalit\xe0 "testo statico", dentro le graffe sei in modalit\xe0 "logica eseguibile".']}),"\n",(0,o.jsxs)(n.p,{children:["Per esempio, quando scrivo ",(0,o.jsx)(n.code,{children:"<h2>{name}</h2>"}),', le graffe dicono "prendi la variabile ',(0,o.jsx)(n.code,{children:"name"}),' ed eseguila come JavaScript". Se scrivo ',(0,o.jsx)(n.code,{children:"<h2>name</h2>"}),' senza graffe, React stampa letteralmente la parola "name" a schermo. Questo spiega perch\xe9 ',(0,o.jsx)(n.code,{children:"style={{ color: 'red' }}"})," ha doppie graffe: la prima coppia \xe8 il portale JavaScript, la seconda \xe8 l'oggetto CSS vero e proprio."]}),"\n",(0,o.jsxs)(n.p,{children:["Sono estremamente contento che il ",(0,o.jsx)(n.strong,{children:"template literal con ternario"})," sia una best practice in React perch\xe9 lo adoravo gi\xe0 in JavaScript vanilla. La sua concisione ma semplicit\xe0 assoluta alla lettura lo rende perfetto: ",(0,o.jsx)(n.code,{children:"{condition ? 's\xec' : 'no'}"})," si legge come se fosse una domanda naturale."]}),"\n",(0,o.jsxs)(n.p,{children:["Ero abituato a vedere ",(0,o.jsx)(n.code,{children:"&&"})," come una condizione per logica booleana (vero o falso), in realt\xe0 funziona anche come operatore che restituisce valori. Quando scrivo ",(0,o.jsx)(n.code,{children:'const risultato = true && "Ciao"'}),", l'operatore vede ",(0,o.jsx)(n.code,{children:"true"}),", va avanti e restituisce ",(0,o.jsx)(n.code,{children:'"Ciao"'}),". Se scrivo ",(0,o.jsx)(n.code,{children:'const risultato = false && "Ciao"'}),", l'operatore vede ",(0,o.jsx)(n.code,{children:"false"}),", si ferma e restituisce ",(0,o.jsx)(n.code,{children:"false"}),". In React questo diventa ",(0,o.jsx)(n.code,{children:"{message && <p>{message}</p>}"}),": se ",(0,o.jsx)(n.code,{children:"message"})," \xe8 una stringa (truthy), React passa al secondo pezzo e renderizza il paragrafo. Se ",(0,o.jsx)(n.code,{children:"message"})," \xe8 stringa vuota (falsy), React si ferma e restituisce ",(0,o.jsx)(n.code,{children:'""'}),", che React ignora completamente (non disegna nulla). React \xe8 programmato per ignorare ",(0,o.jsx)(n.code,{children:"false"}),", ",(0,o.jsx)(n.code,{children:"null"}),", ",(0,o.jsx)(n.code,{children:"undefined"})," e ",(0,o.jsx)(n.code,{children:"true"}),", quindi il rendering condizionale con ",(0,o.jsx)(n.code,{children:"&&"})," funziona perfettamente. Ironicamente, ho capito questo meccanismo di JavaScript non studiando JavaScript stesso, ma React."]}),"\n",(0,o.jsx)(n.h3,{id:"i-componenti-come-funzioni-pure",children:"I Componenti come Funzioni Pure"}),"\n",(0,o.jsx)(n.p,{children:"Ho capito che un componente \xe8 letteralmente una funzione che produce unicamente UI: Props in ingresso \u2192 UI in uscita. Le Props sono immutabili per contratto, il figlio non pu\xf2 modificarle. I dati scorrono solo verso il basso (One-Way Data Flow), quindi se voglio cambiare qualcosa devo cambiare l'input alla fonte nel componente genitore, e React rieseguir\xe0 la funzione del figlio con i nuovi dati."}),"\n",(0,o.jsxs)(n.p,{children:["Nel mio caso pratico: ",(0,o.jsx)(n.code,{children:'<Card name="Mark" />'}),' passa la stringa "Mark" come input alla funzione ',(0,o.jsx)(n.code,{children:"Card"}),". Dentro ",(0,o.jsx)(n.code,{children:"Card"}),", se provo a fare ",(0,o.jsx)(n.code,{children:'name = "Doug"'}),", sto solo riassegnando una variabile locale che viene buttata via al prossimo render. Per cambiare davvero cosa vede l'utente, devo modificare l'array ",(0,o.jsx)(n.code,{children:"profiles"})," dentro ",(0,o.jsx)(n.code,{children:"App"})," (che \xe8 il genitore), e React rieseguir\xe0 automaticamente ",(0,o.jsx)(n.code,{children:"Card"})," con il nuovo valore. \xc8 come nelle catene di montaggio che ci sono nella fabbrica in cui lavoro: il nastro trasportatore (Props) porta i pezzi con l'etichetta gi\xe0 scritta. Io operaio (componente figlio) posso leggere l'etichetta e montare il pezzo di conseguenza, ma non posso cambiare cosa c'\xe8 scritto. Se l'etichetta \xe8 sbagliata, devo fermare la linea e far correggere a monte (nel componente genitore)."]}),"\n",(0,o.jsx)(n.h3,{id:"la-teoria-dellidentit\xe0-keys",children:"La Teoria dell'Identit\xe0 (Keys)"}),"\n",(0,o.jsxs)(n.p,{children:["Quando una lista cambia, React deve decidere se distruggere tutto e rifare o spostare solo certi elementi. Arriva in nostro soccorso la ",(0,o.jsx)(n.code,{children:"key"}),", che non serve a ordinare, bens\xec ad identificare."]}),"\n",(0,o.jsxs)(n.p,{children:["Ad esempio, se ho una lista di tre utenti e uso ",(0,o.jsx)(n.code,{children:"key={index}"}),", le key saranno ",(0,o.jsx)(n.code,{children:"0, 1, 2"}),". Se rimuovo il primo utente, React vede ancora key ",(0,o.jsx)(n.code,{children:"0, 1"})," e pensa \"perfetto, gli utenti 0 e 1 sono ancora qui, devo solo rimuovere il numero 2\". Ma in realt\xe0 l'utente 0 \xe8 stato eliminato, e quelli che vedo ora erano l'1 e il 2. React riutilizzerebbe quindi il nodo DOM sbagliato. Se invece uso ",(0,o.jsx)(n.code,{children:"key={profile.id}"})," con ID univoci tipo ",(0,o.jsx)(n.code,{children:"101, 202, 303"}),", quando rimuovo l'utente 101, React sa esattamente \"l'utente con ID 101 non c'\xe8 pi\xf9, ma 202 e 303 sono ancora qui\". Quindi riutilizzerebbe c
1orrettamente i loro nodi DOM. Ho scoperto che questo diventer\xe0 importantissimo quando avr\xf2 box di input o animazioni, perch\xe9, senza key stabili, il testo che scrive l\u2019utente pu\xf2 \"saltare\" in un'altra casella o sparire completamente perch\xe9 React ha riutilizzato il nodo DOM sbagliato."]}),"\n",(0,o.jsx)(n.h3,{id:"cryptorandomuuid---larma-ideale-per-gli-id",children:"crypto.randomUUID() - L\u2019arma ideale per gli ID"}),"\n",(0,o.jsxs)(n.p,{children:["Un punto su cui mi sono soffermato con molto piacere \xe8 ",(0,o.jsx)(n.code,{children:"crypto.randomUUID()"})," perch\xe9 lo trovo estremamente affascinante nel funzionamento."]}),"\n",(0,o.jsxs)(n.p,{children:["\xc8 una Web API nativa del browser che genera un UUID (Universally Unique Identifier) versione 4. Quando la invochi ottieni una stringa di 36 caratteri tipo ",(0,o.jsx)(n.code,{children:'"c90d075d-53a1-4226-a634-118e69213159"'}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["\xc8 diverso da ",(0,o.jsx)(n.code,{children:"Math.random()"}),", questo perch\xe9 quest\u2019ultimo \xe8 un generatore pseudo-casuale che usa una formula matematica, vale a dire che se conosci il punto di partenza (seed), puoi prevedere i numeri successivi ed esiste una probabilit\xe0 non trascurabile di ottenere lo stesso numero per due volte. ",(0,o.jsx)(n.code,{children:"crypto.randomUUID()"})," invece usa il ",(0,o.jsx)(n.strong,{children:"CSPRNG"})," (Cryptographically Strong Pseudo-Random Number Generator) che attinge all'",(0,o.jsx)(n.strong,{children:"entropia del sistema operativo"}),': movimenti impercettibili del mouse, rumore termico della CPU, timing dei tasti premuti. \xc8 "vero" caso basato sul caos fisico del mondo reale, non solo matematica.']}),"\n",(0,o.jsxs)(n.p,{children:["La probabilit\xe0 di collisione (generare due ID uguali) \xe8 praticamente impossibile. Un UUID ha (2^",122,") combinazioni possibili. Se generassi 1 miliardo di UUID al secondo per i prossimi 85 anni, la probabilit\xe0 di trovarne due uguali sarebbe ancora inferiore a quella di vincere il jackpot del SuperEnalotto per 5 volte consecutive."]}),"\n",(0,o.jsxs)(n.p,{children:["L'errore da evitare \xe8 generare la key durante il render. Se scrivo ",(0,o.jsx)(n.code,{children:"{todos.map(todo => <li key={crypto.randomUUID()}>{todo.text}</li>)}"}),", ogni volta che React ridisegna la lista genera nuove chiavi, pensa che siano tutti elementi nuovi, distrugge il DOM e lo ricrea da zero. Perdo il focus sugli input e devasto le performance. La regola \xe8: genero l'ID ",(0,o.jsx)(n.strong,{children:"solo una volta alla creazione del dato"}),", quando l'utente preme \"Invio\", e lo incollo all'oggetto per sempre. Poi nel JSX uso quell'ID stabile come key."]}),"\n",(0,o.jsxs)(n.p,{children:["Mi sono poi chiesto il costo computazionale e a seguito di qualche ricerca \xe8 emerso che ",(0,o.jsx)(n.code,{children:"crypto.randomUUID()"})," \xe8 circa 20-30 volte pi\xf9 lento di ",(0,o.jsx)(n.code,{children:"Math.random()"})," (400ms vs 15ms per generare 1 milione di ID). Ma per generare UN singolo ID quando l'utente clicca \"Aggiungi Task\", il computer impiega 0.0004 millisecondi. Per dare un metro di paragone l\u2019occhio umano impiega 16 millisecondi per percepire un fotogramma a 60Hz. Generare quindi un UUID \xe8 40.000 volte pi\xf9 veloce di quanto l\u2019occhio possa vedere. Il vero collo di bottiglia nelle app React \xe8 il rendering DOM (10-50ms), non la generazione dell'ID. Preoccuparsi del costo di ",(0,o.jsx)(n.code,{children:"crypto.randomUUID()"})," per fare un analogia, sarebbe come preoccuparsi del peso di un capello mentre si fanno stacchi con un bilanciere da 200kg."]}),"\n",(0,o.jsx)(n.p,{children:"Un altro dubbio che mi \xe8 venuto \xe8 se si potesse integrare in un'applicazione offline first e la risposta \xe8 stata s\xec, ed \xe8 anche molto semplice capirne il motivo, l'entropia viene dal dispositivo locale (rumore hardware, timing), non dal cloud. \xc8 stata una grande scoperta perch\xe9 garantisce anche che se un giorno l'utente sincronizzer\xe0 i dati col cloud, quegli ID non andranno mai in conflitto con quelli di nessun altro utente al mondo."}),"\n",(0,o.jsx)(n.h2,{id:"profile-card",children:"Profile Card"}),"\n",(0,o.jsxs)(n.p,{children:["Il progetto \xe8 stato semplicissimo a livello di implementazione: un array di oggetti (",(0,o.jsx)(n.code,{children:"profiles"}),") mappato in componenti ",(0,o.jsx)(n.code,{children:"<Card />"})," con destructuring delle Props."]}),"\n",(0,o.jsxs)(n.p,{children:['La parte interessante non \xe8 stata
1il "cosa" (tre card in fila), ma il "come". Ho separato completamente l\'array di dati dalla logica di rendering: il componente ',(0,o.jsx)(n.code,{children:"<Card />"})," \xe8 totalmente riutilizzabile perch\xe9 non sa nulla dei dati specifici che riceve, lavora solo con le Props che gli arrivano. Ho usato ",(0,o.jsx)(n.code,{children:".map()"})," per iterare sull'array e generare JSX dinamicamente, e ogni card ha ricevuto ",(0,o.jsx)(n.code,{children:"key={profile.id}"})," per dare a React un'identit\xe0 stabile con cui tracciare ogni elemento."]}),"\n",(0,o.jsxs)(n.p,{children:["\xc8 la prima volta che vedo una ",(0,o.jsx)(n.strong,{children:"vera"}),' separazione tra Dati e Vista. In Calcola Turno avevo HTML separato da JavaScript, ma il JS doveva "conoscere" la struttura DOM per manipolarla (',(0,o.jsx)(n.code,{children:"document.getElementById"}),", ",(0,o.jsx)(n.code,{children:"appendChild"}),"). Se cambiavo l'HTML, il JS si rompeva. Qui invece ",(0,o.jsx)(n.code,{children:"<Card />"})," \xe8 totalmente cieco: non sa se i dati vengono da un array locale, da un server, o da un database. Riceve Props e renderizza, punto. Se domani cambio la sorgente dati, il componente non lo sa nemmeno."]}),"\n",(0,o.jsx)(n.h2,{id:"cosa-ho-imparato",children:"Cosa Ho Imparato"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Destructuring Props direttamente nei parametri:"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"function Card({ name, title, bio })"})," invece di ",(0,o.jsx)(n.code,{children:"function Card(props)"})," + ",(0,o.jsx)(n.code,{children:"props.name"}),". Pi\xf9 pulito, autocomplete dell'IDE funziona meglio, e si vede immediatamente cosa si aspetta il componente."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.strong,{children:[(0,o.jsx)(n.code,{children:".map()"}
1)," come Core Pattern di React:"]})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:['Trasformare array di dati in array di JSX \xe8 il pattern pi\xf9 usato in React. Non \xe8 "magia React", \xe8 ',(0,o.jsx)(n.code,{children:".map()"})," JavaScript standard che restituisce valori renderizzabili."]}),"\n",(0,o.jsxs)(n.li,{children:["Pattern: ",(0,o.jsx)(n.code,{children:"{array.map(item => <Component key={item.id} {...item} />)}"}),". Essenziale capire che ogni iterazione deve restituire un elemento React valido."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"One-Way Data Flow (Unidirezionalit\xe0):"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["I dati vivono nel componente padre (",(0,o.jsx)(n.code,{children:"App"}),"), scorrono verso i figli (",(0,o.jsx)(n.code,{children:"Card"}),") via Props, ma i figli non possono modificarli. Se il figlio deve comunicare verso l'alto, dovr\xe0 farlo via callback (concetto che vedr\xf2 presto con gli Event Handler)."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Separazione tra Container e Presentational Components:"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"App"})," \xe8 il ",(0,o.jsx)(n.strong,{children:"Container"}),": gestisce i dati, orchestra i figli."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"Card"})," \xe8 ",(0,o.jsx)(n.strong,{children:"Presentational"}),": riceve Props, renderizza UI, non sa nulla del contesto pi\xf9 ampio."]}),"\n",(0,o.jsxs)(n.li,{children:["Questo pattern rende ",(0,o.jsx)(n.code,{children:"<Card />"})," riutilizzabile: posso usarlo in 10 posti diversi con dati diversi."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"JSX come Espressione JavaScript:"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Il ",(0,o.jsx)(n.code,{children:"return"})," di ",(0,o.jsx)(n.code,{children:".map()"})," restituisce JSX, che sotto il cofano \xe8 un oggetto JavaScript. React raccoglie tutti questi oggetti in un array e li renderizza."]}),"\n",(0,o.jsxs)(n.li,{children:["Questo spiega perch\xe9 posso fare ",(0,o.jsx)(n.code,{children:"const cards = profiles.map(...)"})," e poi ",(0,o.jsx)(n.code,{children:"return <div>{cards}</div>"}),". JSX \xe8 solo sintassi, non cambia la natura di JavaScript."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Immutabilit\xe0 delle Props (Read-Only Contract):"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Se provo a fare ",(0,o.jsx)(n.code,{children:'name = "altro"'})," dentro ",(0,o.jsx)(n.code,{children:"<Card />"}),", React non esplode, ma sto violando il contratto. Le Props sono pensate come input immutabili. Se servono dati mutabili, user\xf2 lo State (prossimo step)."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Flex Container per Layout Responsivo:"})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:'className="flex-container"'})," nel CSS usa probabilmente Flexbox per disporre le card in riga con wrap automatico. Questo prepara mentalmente al fatto che React gestisce la logica, CSS gestisce il layout."]}),"\n"]}),"\n",(0,o.jsx)(n.hr,{}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Next"}),":",(0,o.jsx)(n.br,{}),"\n","Creare una Mood Board (Labs)."]})]})}function m(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},3086:(e,n,a)=>{a.d(n,{A:()=>i});const i=a.p+"assets/images/profile-card-fb13bc7d9fe50bdbe127c7e0b978e7a0.webp"},8453:(e,n,a)=>{a.d(n,{R:()=>t,x:()=>l});var i=a(6540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}},9365:(e,n,a)=>{a.d(n,{A:()=>t});a(6540);var i=a(4164);const o={tabItem:"tabItem_Ymn6"};var r=a(4848);function t({children:e,hidden:n,className:a}){return(0,r.jsx)("div",{role:"tabpanel",className:(0,i.A)(o.tabItem,a),hidden:n,children:e})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.