Els components sovint necessiten canviar el que apareix a la pantalla com a resultat d'una interacció.
Introducció
Crea un nou projecte amb el nom react-state:
Esdeveniment
React et permet afegir controladors d’esdeveniments al teu TSX.
A continuació tens un botó que quan hi fas clic no fa res:
return <button className="btn btn-primary m-5">No hago nada</button>
}Un controlador d’esdeveniment és una funció que s’executarà quan l’usuari faci alguna cosa:
// Controlador de evento
}
return <button className="btn btn-primary m-5">No hago nada</button>
}Pots confirmar que el botó no fa res i la funció mai s’executa 🥳
El botó té la propietat “nullable” onClick?, el valor de la qual és una funció que s’executarà quan l’usuari faci clic al botó:
// Controlador de evento
}
return <button className="btn btn-primary m-5" onClick=>No hago nada</button>
}Ara quan fas clic al botó, el navegador detecta aquest esdeveniment, i com que la propietat onClick del botó no és nul·la, crida a la funció corresponent.
Per conveni, és comú anomenar els controladors d’esdeveniments com handle seguit del nom de l’esdeveniment.
Sovint veuràs onClick={handleClick}, onMouseEnter={handleMouseEnter}, etcètera.
Afegeix un controlador per a onMouseEnter?:
// Controlador de evento
}
}
return <button
className="btn btn-primary m-5"
onClick=
onMouseEnter=
>
No hago nada
</button>
}També pots passar directament una funció en lloc d’una referència a una funció:
return <button
className="btn btn-primary m-5"
onClick= onMouseLeave= >
Hago algo
</button>
}A continuació tens un text editable:
return <p
className="m-5 p-2 border"
contentEditable="true"
onKeyUp= >
En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lantejas los viernes, algún palomino de añadidura los domingos, consumían las tres partes de su hacienda. El resto della concluían sayo de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo mesmo, y los días de entresemana se honraba con su vellorí de lo más fino. Tenía en su casa una ama que pasaba de los cuarenta, y una sobrina que no llegaba a los veinte, y un mozo de campo y plaza, que así ensillaba el rocín como tomaba la podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años; era de complexión recia, seco de carnes, enjuto de rostro, gran madrugador y amigo de la caza. Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en esto hay alguna diferencia en los autores que deste caso escriben; aunque por conjeturas verosímiles se deja entender que se llamaba Quijana. Pero esto importa poco a nuestro cuento: basta que en la narración dél no se salga un punto de la verdad.</p>
}El text és editable perquè l’atribut contentEditable de l’element <p> és “true” (fes clic a dins i comença a escriure).
Afegeix algunes funcions més que responguin a esdeveniments diferents.
Si no saps quins, escriu on i deixa que l’editor et suggereixi les opcions disponibles.
Propietats
Com els controladors d’esdeveniments són declarats dins d’un component, tenen accés a les props del component.
Crea un component MessageButton:
return <div>
<MessageButton message="Hola" />
<MessageButton message="Adiós" />
</div>
}
return <button className="btn btn-primary m-5" onClick= Hago algo
</button>
}Ara tens dos botons que mostren missatges diferents, però que tenen el mateix text.
Modifica el codi per passar com a prop el contingut del botó:
return <div>
<MessageButton message="Hola">Bienvenido al club</MessageButton>
<MessageButton message="Adiós">
<img src="https://www.flaticon.com/download/icon/1998592?icon_id=1998592&author=219&team=219&pack=1998559&style=Lineal+Color&style_id=914&format=png&color=%23000000&colored=2&size=64&selection=1&type=standard" />
</MessageButton>
</div>
)
}
return <button className="btn btn-primary m-5" onClick=
</button>
}Pots veure que children és una prop especial de tipus any que es pot passar com si escrivissis HTML (és un objecte que conté els elements que embolcalla un component).
També pots passar com a prop el controlador d’esdeveniment:
return <div>
<MessageButton onClick= Playa
</MessageButton>
<MessageButton onClick= Montaña
</MessageButton>
</div>
)
}
return <button className="btn btn-primary m-5" onClick=>
</button>
}Variables
Mostrar alertes no és la forma més eficient de mostrar missatges a l’usuari.
És millor utilitzar una variable:
let message = "Hola Mundo"
return <div className="m-5">
<p className="ms-5"></p>
<MessageButton onClick=>
Playa
</MessageButton>
<MessageButton onClick=>
Montaña
</MessageButton>
</div>
)
}
return <button className="btn btn-primary m-5" onClick=>
</button>
}No et preocupis si el missatge no canvia, el codi funciona, però React no reacciona al canvi del contingut de la variable message.
Estat
Comencem amb un exemple senzill:
let message = "Hola Mundo"
return <div className="m-5">
<p></p>
<button className="btn btn-primary mt-3" onClick=>
Mensaje
</button>
</div>
)
}Com era d’esperar React no reacciona al canvi del contingut de la variable message.
React funciona d’aquesta manera:
-
Renderitza l’aplicació
-
Si es modifica una variable d’estat, React reacciona i torna a renderitzar els components afectats.
El Hook d’useState ofereix dues coses:
- Una variable d’estat per mantenir les dades entre renderitzats.
- Una funció que estableix l’estat per actualitzar la variable i provocar que React renderitzi el component novament.
Per afegir una variable d’estat, hem d’importar l’useState de React a l’inici de l’arxiu:
;I ja pots crear una variable amb estat:
const =
return <div className="m-5">
<p></p>
<button className="btn btn-primary mt-3"
onClick= Mensaje
</button>
</div>
)
}L’únic argument per a useState és el valor inicial de la seva variable d’estat.
En aquest exemple, el valor inicial de message s’estableix en "Hola Món".
Cada vegada que el component es renderitza, l’useState retorna un array que conté dos valors:
- La variable d’estat (
message) amb el valor que has emmagatzemat. - La funció que estableix l’estat (
setMessage) que pot actualitzar la variable d’estat i alertar React perquè renderitzi el component novament.
Modifica aquest codi per utilitzar una variable d’estat:
let message = "Hola Mundo"
return <div className="m-5">
<p className="ms-5"></p>
<MessageButton onClick=>
Playa
</MessageButton>
<MessageButton onClick=>
Montaña
</MessageButton>
</div>
)
}
return <button className="btn btn-primary m-5" onClick=>
</button>
}Show solution
const =
return <div className="m-5">
<p className="ms-5"></p>
<MessageButton onClick= Playa
</MessageButton>
<MessageButton onClick= Montaña
</MessageButton>
</div>
)
}
return <button className="btn btn-primary m-5" onClick=>
</button>
}Múltiples variables d’estat
Podem tenir més d’una variable d’estat de diferents tipus en un component.
A continuació tens un codi que utilitza 4 variables d’estat:
const =
const =
const =
const =
const guess =
}
}
}
}
return <div className="m-5">
<p></p>
</div>
)
}Activitat. Afegeix un botó per reiniciar el joc.
És una bona idea tenir múltiples variables d’estat si no es troben relacionades entre si, però si trobem que sovint canviem dues variables d’estat juntes, podria ser millor combinar-les en una sola.
TODO Exemple
L’estat és aïllat i privat
L’estat és local per a una instància de component a la pantalla.
En altres paraules, si renderitzes el mateix component dues vegades, cada còpia tindrà un estat completament aïllat.
return <div>
<Message text="☘ A la tercera va la vencida." />
<Message text="🌷 Al mal tiempo, buena cara." />
</div>
)
const =
}
return <div className="m-5">
<p className=`}>{text}</p>
<button onClick= <span className="fs-1">+</span>
</button>
</div>
)
}
}Pots veure en el nostre exemple, que el component Message es renderitza dues vegades i que són completament independents.
Activitat - Receptes
A continuació tens el codi inicial amb una llista de menjars en les quals només es mostra un menjar.
type Meal = name: string
ingredients: string
image: string
}
const meals: Meal = "name": "Classic Margherita Pizza",
"ingredients": ,
"image": "https://cdn.dummyjson.com/recipe-images/1.webp",
},
"name": "Vegetarian Stir-Fry",
"ingredients": ,
"image": "https://cdn.dummyjson.com/recipe-images/2.webp",
},
"name": "Chocolate Chip Cookies",
"ingredients": ,
"image": "https://cdn.dummyjson.com/recipe-images/3.webp",
},
"name": "Chicken Alfredo Pasta",
"ingredients": ,
"image": "https://cdn.dummyjson.com/recipe-images/4.webp",
},
"name": "Mango Salsa Chicken",
"ingredients": ,
"image": "https://cdn.dummyjson.com/recipe-images/5.webp",
}
]
const meal = meals
return <div className="container m-5">
<h5></h5>
<div className="row">
<div className="col-3"><img className="img-fluid" src= /></div>
</div>
</div>
)
}Afegeix un botó per mostrar els ingredients que componen el menjar:
Show solution
Afegeix dos botons: un per anar al següent plat i un altre per anar al plat anterior.
Show solution
Activitat - Netlify
Crea una mini aplicació a la teva elecció amb router i estat.
Desplega l’aplicació a Netlify