Condicionales, bucles y props
Resumen
Avanzando un poco más en el mundo React, vemos como debe hacerse un if, if-else y un map en JSX. Para potenciar esto, usamos los props para pasar información de componentes padres a hijos y es una genialidad.
También, avanzamos con el portfolio para pasarle info a cada componente, mezclando los temas de hoy.
Podrás ver la lista de los 100 días en este enlace.
Condicionales y bucles en JSX
JSX nos permite meter contenido dinámico dentro de HTML. Podemos crear condicionales simples, ternarios y bucles adentro.
- Condicionales simples
{
testState == 10 && <p>El valor es 10</p>;
}
Esto se lee así: "Si testState
es igual a 10, entonces (el &&
)..." y lo que haya dentro del parentesis.
- Ternarios
{
esMayorDeEdad >= 18 ? <p>Es mayor</p> : <p>Es menor</p>;
}
Cambia un poco, pero el "entonces" condicional simple ahora es ?
, y el "si no", es :
.
- Bucles
<ul>
{arrayNumeros.map((num, key) => {
return <li key={key}>Soy el numero {num}</li>;
})}
</ul>
En JSX solo nos permiten utilizar bucles funcionales, así que solo podemos usar map con arrow function. Adentro debe tener un return con el HTML que queremos que se vea.
React necesita que le identifiquemos cada vuelta que hagamos con map, entonces le pasamos como segundo argumento el atributo key
. Esto se ve mejor en la práctica.
Podemos usar condicionales y ternarios para saber si la person es mayor o no:
function App() {
const [age, setAge] = useState(0);
function handleChange(e) {
const { valueAsNumber } = e.target; // Usamos valueAsNumber
setAge(valueAsNumber); //porque el input es number
}
return (
<div>
<input type="number" onChange={handleChange} />
{age > 0 && (
// El <> ... </> se conoce como React fragment.
//Es un falso bloque de HTML
<>{age >= 18 ? <p>Sos grande</p> : <p>Sos chikito</p>}</>
)}
</div>
);
}
El condicional nos permite iniciar el documento sin ningún aviso. Solo si el número es mayor a 0, empieza a darnos un mensaje.
Usamos valueAsNumber
en lugar de value
porque estamos operando con números, no con strings; por lo tanto podemos usar valueAsNumber
para evitar parsear el string de value
.
Un ejemplo de bucles, sería armar una lista de números ingresados desde un input. Cada número se agrega a la lista cliqueando un botón.
function App() {
const [inputNumber, setInputNumber] = useState(0);
const [arrNumeros, setArrNumeros] = useState([]);
function handleChange(e) {
const { valueAsNumber } = e.target;
setInputNumber(valueAsNumber);
}
function handleClick() {
const newArr = [...arrNumeros, inputNumber];
setArrNumeros(newArr);
setInputNumber("");
}
return (
<div>
<input type="number" onChange={handleChange} value={inputNumber} />
<button onClick={handleClick}>Agregar al array</button>
<ul>
{arrNumeros.map((num, key) => {
return <li key={key}>{num}</li>;
})}
</ul>
</div>
);
}
El spread operator (...
) lo que hace es clonar el contenido de un objeto o array, pero también clonando el puntero memoria. O sea, cuando guardamos un array, se guarda en un espacio de memoria de nuestra computadora en una cierta dirección. Entonces, para guardar nuevos valores, lo que hacemos tener una referencia del espacio de memoria, o clonando el espacio.
Lo que hace este componente App
es: Ingreso número y los cambios se guardan en inputNumber
por medio de la función handleChange
. Al apretar el botón, se dispara la otra función handleClick
que, obtiene el estado anterior del array de números arrNumeros
y agrega el valor previo del otro estado inputNumber
.
Tenemos dentro del JSX un bucle dentro de las etiquetas ul
que mapea el estado interno arrNumeros
y los agrega al listado como un item li
.
Si lo miran bien, este es el funcionamiento básico de un ToDo list.
Props
Sirve para pasar información entre componentes padres a componentes hijos. No puede ser en el sentido contrario!
La forma de pasar información es escribirlas como si fueran atributos de HTML.
En el componente padre:
<Child propDePrueba="valordePrueba" />
En el componente hijo:
function Child(props) {
console.log(props);
return <p>{props.propDePrueba}</p>;
}
En el caso del Blog que estabamos haciendo días antes, habíamos dejado hardcodeados el título y párrafo. Si queremos hacer otros títulos y párrafos, es inhumano hacerlo así.
Usaremos los props para que podamos darle una manera más eficaz de pasarle un título y un párrafo, si tener que ir hasta el último componente hijo.
- En
App.js
le damos dos componentesBlog
.
function App() {
return (
<div>
<Blog
title="Titulo muy copado"
content="Parrafo muy copado en Dev.to"
/>
<Blog
title="Otro titulo by El Javo"
content="Parrafo hecho gracias a Course.It"
/>
</div>
);
}
- En
index.js
del componenteBlog
, obtenemos los props así:
function Blog(props) {
const { title, content } = props;
return (
<section>
<Title title={title} />
<Text content={content} />
</section>
);
}
- En
index.js
del componenteTitle
:
function Title(props) {
const { title } = props;
return <h3>{title}</h3>;
}
- Y por último, en
index.js
del componenteText
function Text(props) {
const { content } = props;
return <p>{content}</p>;
}
Práctica
Ahora si, volviendo al portfolio, vamos a utilizar el concepto de props y bucles para pasar un array de objetos al navbar y a las tarjetas que muestra cada proyecto.
- En
App.js
tenemos:
function App() {
const menuArr = [
{
text: "Home",
url: "#home",
},
{
text: "About me",
url: "#home",
},
{
text: "Projects",
url: "#home",
},
{
text: "Skills",
url: "#home",
},
{
text: "Contact",
url: "#home",
},
];
const projectArr = [
{
photo: "https://picsum.photos/300/200?a",
title: "\"Titulo prueba\","
description: "\"Descripcion de prueba, a ver si funca esto\","
tecno: "HTML CSS JS",
},
{
photo: "https://picsum.photos/300/200?a",
title: "\"Titulo prueba 2\","
description: "\"Descripcion de prueba 2, a ver si funca esto tambien\","
tecno: "texto plano",
},
];
return (
<div>
<Nav menuArr={menuArr} />
<Projects projectArr={projectArr} />
</div>
);
}
- En
index.js
del componente Nav:
function Nav(props) {
const { menuArr } = props;
return (
<div>
{menuArr.map((menu, key) => {
return <Menu menu={menu} key={key} />;
})}
</div>
);
}
- En
index.js
del componenteMenu
:
function Menu(props) {
const { text, url } = props.menu;
return <a href={url}>{text}</a>;
}
- En
index.js
del componenteProjects
:
function Projects(props) {
const { projectArr } = props;
return (
<section>
{projectArr.map((project, key) => {
return <Card project={project} key={key} />;
})}
</section>
);
}
- Y por último, en
index.js
del componenteCard
:
function Nav(props) {
const { photo, title, description, tecno } = props.project;
return (
<div>
<figure>
<img src={photo} alt={title} />
</figure>
<h2>{title}</h2>
<p>{description}</p>
<h3>Tecnologías</h3>
<figure>{tecno}</figure>
</div>
);
}
Más adelante, veremos si con los temas restantes podemos usarlos para el portfolio. Ahora mismo ya puede armarse algo lindo.
Día 10/100
Top comments (0)