En esta tercera entrada de la serie sobre React.js vamos a ver las propiedades. Básicamente, las propiedades sirven para pasar información de un componente padre a un componente hijo. En cuanto a la sintaxis, desde el padre sería como un atributo de HTML (propiedad=»valor») y para acceder desde el hijo, se hace a través del objeto props. Como nota, es importante saber que las propiedades son inmutables, es decir, no se deberían modificar ni actualizar. También hay que tener en cuenta que React tiene reservadas ciertas propiedades ( className , onClick , onChange , etc.), por tanto, nosotros no podremos ponerle ningún nombre de estos a nuestras propiedades.
Propiedades en componentes
Para este post voy a seguir utilizando el ejemplo del post anterior. Dicho esto, vamos a crear un listado de posts con un componente llamado PostList que tendrá unos componentes hijos llamados PostItem a los cuales les pasaremos la información del post desde PostList (el padre) y la mostraremos.
Creamos el componente PostItem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import React from "react"; import PropTypes from "prop-types"; const PostItem = props => { return ( <div> <h1>{props.title}</h1> <p>{props.content}</p> </div> ); }; PostItem.propTypes = { title: PropTypes.string.isRequired, content: PropTypes.string.isRequired }; export default PostItem; |
Estamos utilizando un Stateless Component, porque será un componente solo de mostrado ya que, en principio, no tendrá estado. Al ser un Stateless Component, a las propiedades se acceden pasándolas por parámetro en la función. Si fuese un Class Component se accederían a través de this.props . En este caso sería this.props.title y this.props.content .
También, estamos importando PropTypes que lo utilizamos para comprobar que las propiedades que recibimos son del tipo que queremos. En este caso, un string y que son requeridas. Si no cumpliese alguna de estas reglas, nos saldría un error en la consola del navegador.
Ahora vamos a crear un componente para el listado llamado PostList:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import React from "react"; import PostItem from "./PostItem"; class PostList extends React.Component { render() { return ( <div> <PostItem title="Post Title 1" content="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." /> <PostItem title="Post Title 2" content="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." /> </div> ); } } export default PostList; |
Estamos llamando al componente creado anteriormente y le estamos pasando las propiedades que hemos puesto como requeridos.
Lo único que nos falta es llamar al componente PostList desde el componente principal (App) para mostrar todo. Primero importaremos el componente PostList y después lo llamaremos dentro del método render:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import PostList from "./components/PostList"; ... render() { return ( <div> <Header /> <PostList /> <Footer /> </div> ); } ... |
Ahora si arrancamos el servidor de desarrollo, veremos lo siguiente:
Una vez ya tenemos esto, vamos a mejorarlo un poco. Lo que vamos a hacer va a ser, en vez de pasarle dos propiedades (title y content) al componente PostItem, le vamos pasar una propiedad llamada post en formato JSON y así lo simplificamos.
Para ello, vamos al componente PostItem y lo adaptamos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import React from "react"; import PropTypes from "prop-types"; const PostItem = props => { return ( <div> <h1>{props.post.title}</h1> <p>{props.post.content}</p> </div> ); }; PostItem.propTypes = { post: PropTypes.shape({ title: PropTypes.string.isRequired, content: PropTypes.string.isRequired }) }; export default PostItem; |
En cuanto a las propiedades, estamos accediendo primero al objeto post y después a las propiedades title y content del objeto. En cuanto a los PropTypes, se ha modificado para que acepte un objeto con las propiedades title y content , pero el funcionamiento es el mismo.
Ahora vamos a modficar el componente PostList:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import React from "react"; import PostItem from "./PostItem"; class PostList extends React.Component { render() { return ( <div> <PostItem post={{ title: "Post Title 1", content: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." }} /> <PostItem post={{ title: "Post Title 2", content: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." }} /> </div> ); } } export default PostList; |
Como ves, ha cambiado la forma en la que se pasan las propiedades. Se ponen 2 corchetes ({{}}) y dentro se ponen las propiedades. Se ponen 2 corchetes, porque el primero indica a React.js que es JS y el segundo es para formar el JSON.
Hecho esto, si vamos al navegador y todo ha ido bien, veremos el mismo resultado que antes, pero internamente es diferente.
Aplicar estilos a componentes
Aprovechando que estamos viendo las propiedades, vamos a ver como aplicar estilos a los componentes. Primero de todo, hay que decir que hay muchas formas de aplicar estilos a los componentes, cada una con sus ventajas e inconvenientes. En esta entrada, vamos a ver las más básicas de todas que son los estilos en línea y los archivos CSS. En entradas posteriores, veremos más en profundidad las demás opciones, pero como esta entrada trata sobre propiedades veremos las mencionadas anteriormente.
Archivo CSS
El funcionamiento es básicamente como un archivo de CSS incrustado en un HTML. Creamos el archivo CSS en la raiz del proyecto:
1 2 3 4 5 6 7 |
header { text-align: center; } .nav a { margin-right: 10px; } |
Importamos el CSS desde App.js:
1 |
import "./styles.css"; |
Y aplicamos la clase nav en Header:
1 2 3 4 5 6 7 8 9 10 11 |
... <header> <div>Logo</div> <nav className="nav"> <a href="#/">Home</a> <a href="#/">Blog</a> <a href="#/">Photos</a> <a href="#/">Contact</a> </nav> </header> ... |
Si te fijas, estamos utilzando la propiedad className y no class como sería en HTML.
Con esto, si entramos al navegador deberemos ver lo siguiente:
Uno de los inconvenientes al utilizar esta manera será que los estilos serán globales y no locales por componente. Esto hará que se puedan ver afectados componentes que a lo mejor no deberían.
Estilos en línea
Vamos a aplicarlos al componente Footer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import React from "react"; const style = { textAlign: "center", fontWeight: "bold", marginTop: "50px" }; // function component const Footer = props => { return ( <footer style={style}> <p>Copyright ©</p> </footer> ); }; export default Footer; |
Creamos un objeto con las propiedades CSS y lo llamamos desde la propiedad style del componente que queremos aplicarle los estilos.
Esta opción tiene bastantes inconvenientes. Algunos de ellos son que no se pueden utilizar media queries, no se pueden utilizar selectores CSS como clases, id o elementos, se tiene que utilizar una sintaxis camel case para las propiedades CSS, entre otras.
El resultado sería este:
Como he comentado antes, hemos visto estas dos opciones porque tienen que ver con las propiedades, pero como puedes ver no son las mejores opciones que existen, éstas las veremos más adelante.
Si quieres ver el ejemplo de esta entrada en vivo, puedes verlo en este enlace: https://repl.it/@vreaxe/Reactjs-Propiedades-y-aplicar-estilos-a-los-componentes