DEV Community

Cover image for #CienDiasConCourseIt: Día 10/100
Javier Rodriguez
Javier Rodriguez

Posted on

#CienDiasConCourseIt: Día 10/100

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>;
}
Enter fullscreen mode Exit fullscreen mode

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>;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
    );
}
Enter fullscreen mode Exit fullscreen mode

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>
    );
}
Enter fullscreen mode Exit fullscreen mode

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" />
Enter fullscreen mode Exit fullscreen mode

En el componente hijo:

function Child(props) {
    console.log(props);

    return <p>{props.propDePrueba}</p>;
}
Enter fullscreen mode Exit fullscreen mode

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 componentes Blog.
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>
    );
}
Enter fullscreen mode Exit fullscreen mode
  • En index.js del componente Blog, obtenemos los props así:
function Blog(props) {
    const { title, content } = props;
    return (
        <section>
            <Title title={title} />
            <Text content={content} />
        </section>
    );
}
Enter fullscreen mode Exit fullscreen mode
  • En index.js del componente Title:
function Title(props) {
    const { title } = props;
    return <h3>{title}</h3>;
}
Enter fullscreen mode Exit fullscreen mode
  • Y por último, en index.js del componente Text
function Text(props) {
    const { content } = props;
    return <p>{content}</p>;
}
Enter fullscreen mode Exit fullscreen mode

Esto nos quedaría algo así:
Alt Text

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>
    );
}
Enter fullscreen mode Exit fullscreen mode
  • 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>
    );
}
Enter fullscreen mode Exit fullscreen mode
  • En index.js del componente Menu:
function Menu(props) {
    const { text, url } = props.menu;
    return <a href={url}>{text}</a>;
}
Enter fullscreen mode Exit fullscreen mode
  • En index.js del componente Projects:
function Projects(props) {
    const { projectArr } = props;
    return (
        <section>
            {projectArr.map((project, key) => {
                return <Card project={project} key={key} />;
            })}
        </section>
    );
}
Enter fullscreen mode Exit fullscreen mode
  • Y por último, en index.js del componente Card:
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>
    );
}
Enter fullscreen mode Exit fullscreen mode

Así, obtenemos esta imagen:
Alt Text

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)