No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Iconos con colores dinámicos

12/34
Recursos

Aportes 35

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

¡¡¡Si como a mí casi se te estalla la cabeza!!!, espero este resumen te ayude un poco.

  • Debemos partir desde App.js que es el primer lugar en el cual enviamos una función encapsulada (el termino oficial es Render Props: “se refiere a una técnica para compartir código entre componentes en React utilizando una propiedad cuyo valor es una función ”) dentro de una prop a cada uno de los componentes TodoItem que se crean.
    [Render Props - documentación]
    (https://es.legacy.reactjs.org/docs/render-props.html)![1.jpg]

  • Como se aprecia estamos pasan esa función en onComplete y onDelete.
    Luego en nuestro componente TodoItem las recibimos y nuevamente las pasamos en una prop que volvemos a llamar onComplete y onDelete(El pro las llama onClick).

    Finalmente las recibiremos en nuestros componentes DeleteIcon y CompleteIcon respectivamente, y es ahí donde si crearemos ese evento que las ejecutará.

En resumen:

El tema de los iconos parece complicarse bastante en este caso cuando son personalizados… En mi caso desde hace varias clases ya tenia bajo recomendacion de otro companero unos iconos importados desde Font Awesome y logre solucionar estos problemas facilmente con CSS y algun que otro condicional sin recurrir a nuevos componentes, pero me imagino que para aplicaciones mas personalizadas si o si toca hacer esto…

Yo use css para el cambio de colores de los íconos…pero no sé si sea escalable o no ello

La verdad me parece gracioso que mucha gente se queja por que en platzi los cursos no son avanzados ni profundos, pero llega un tema como este que seguramente se tendra que hacer en la vida real y todos dicen “eso con una libreria sale”. Claro eso es logico pero se les olvida que una empresa que contrata un desarrollador que sepa React.js la mayoria de veces lo hace por que quiere cosas personalizadas, y en ese caso no saber hacer esto va a ser un verdadero problema.

BOOOM == Toma tu dolor de cabeza.

Clase 11 - Iconos en React: librerías y SVG

Primero usaramos los react-icons bastante comoda y facil desde varias librerias y formatos:

npm install react-icons --save

Y la manera de usarlos es bastante sencilla, primero debemos importar el icono:

import { FaBeer } from 'react-icons/fa';

Y luego dentro del codigo lo usamos como si fuera un componente:

return <h3> Lets go for a <FaBeer />? </h3>

Pero en la clase usaremos los iconos hechos por el Team Platzi!.

Bueno lo primero es definir dos archivos con los nombres de los iconos:
CompleteIcon.js:

import React from "react";
import { TodoIcon } from './TodoIcon';

function CompleteIcon({ completed, onComplete }) {
  return (
    <TodoIcon
      type="check"
      color={completed ? "green" : "gray"}
      onClick={onComplete}
    />
  );
}

export { CompleteIcon };

Y DeleteIcon.js:

import React from "react";
import { TodoIcon } from "./TodoIcon";

function DeleteIcon({ onDelete }) {
  return <TodoIcon type="delete" color="gray" onClick={onDelete} />;
}
export { DeleteIcon };

Ahora debemos, crear un 3er archivos TodoIcon.js, dentro de este importamos los svg del TeamPLatzi (que tambien deben estar dentro de un archivo independiente) con los nombres de check.svg:

<svg viewBox="0 0 405.272 405.272" xml:space="preserve">
<path d="M393.401,124.425L179.603,338.208c-15.832,15.835-41.514,15.835-57.361,0L11.878,227.836 c-15.838-15.835-15.838-41.52,0-57.358c15.841-15.841,41.521-15.841,57.355-0.006l81.698,81.699L336.037,67.064 c15.841-15.841,41.523-15.829,57.358,0C409.23,82.902,409.23,108.578,393.401,124.425z"/>
</svg>

Y delete.svg:

<svg viewBox="0 0 348.333 348.334" xml:space="preserve">
<path d="M336.559,68.611L231.016,174.165l105.543,105.549c15.699,15.705,15.699,41.145,0,56.85 c-7.844,7.844-18.128,11.769-28.407,11.769c-10.296,0-20.581-3.919-28.419-11.769L174.167,231.003L68.609,336.563 c-7.843,7.844-18.128,11.769-28.416,11.769c-10.285,0-20.563-3.919-28.413-11.769c-15.699-15.698-15.699-41.139,0-56.85 l105.54-105.549L11.774,68.611c-15.699-15.699-15.699-41.145,0-56.844c15.696-15.687,41.127-15.687,56.829,0l105.563,105.554 L279.721,11.767c15.705-15.687,41.139-15.687,56.832,0C352.258,27.466,352.258,52.912,336.559,68.611z"/>
</svg>

Y el archivo TodoIcon tambien lo creamos conjuntamente con su .css:
TodoIcon.js:

import { ReactComponent as CheckSVG } from "./check.svg";
import { ReactComponent as DeleteSVG } from "./delete.svg";
import "./TodoIcon.css";

const iconTypes = {
  check: (color) => <CheckSVG className="Icon-svg" fill={color} />,
  delete: (color) => <DeleteSVG className="Icon-svg" fill={color} />,
};

function TodoIcon({ type, color, onClick }) {
  return (
    <span className={`Icon-container Icon-container-${type}`} onClick={onClick}>
      {iconTypes[type](color)}
    </span>
  );
}

export { TodoIcon };

TodoIcon.css:

.Icon-container {
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 48px;
    width: 48px;
    font-size: 24px;
    font-weight: bold;
    /* background-color: #CCC; */
  }
  
  .Icon-container-check {
    position: absolute;
    left: 12px;
  }
  .Icon-container-check--active {
    color: #4caf50;
  }
  
  .Icon-container-delete {
    position: absolute;
    top: -24px;
    right: 0;
  }
  .Icon-container-delete:hover {
    color: red;
  }
  
  .Icon-svg {
    width: 24px;
    height: 24px;
  }
  
  .Icon-container-check:hover .Icon-svg {
    fill: green;
  }
  .Icon-container-delete:hover .Icon-svg {
    fill: red;
  }

Esto ya se esta poniendo todo muy loco !!

Yo normalmente uso https://boxicons.com/. Es bastante sencillo, lo importo como una fuente en mi archivo html y ya después voy llamando cada icono con la etiqueta <i> que me bota directamente la documentación que está en la página. Y como es una fuente pues es muy facil cambiarle el color tambíen.

Buen momento para… Keep to calm and carry on!, Sé que al inicio la cabeza estalla, pero vengo del futuro y mi consejo es:

Sigue escribiendo y practicando con el codigo. No te desanimes y sigue tu aprendizaje. Verás como con el tiempo entiendes absolutamente todo y te sientes muy feliz de como has avanzado.

Aquí mi aporte, es un resumen de cómo entendí este proceso de renderizar SVG’s de forma dinámica. Felíz de leer cualquier retroalimentación con respecto al resumen. https://docs.google.com/document/d/1-TpxgF5jstVo_fEFx3OwHBOCFoUKvcGQ/edit?usp=sharing&ouid=105845221325245106883&rtpof=true&sd=true

Totalmente engorroso 😦

En esta sección, nos enfocaremos en mejorar la presentación y funcionalidad de nuestra aplicación mediante la implementación de íconos y eventos en React.

Íconos Personalizados con TodoIcon Library

  • Hemos creado una biblioteca de íconos personalizados llamada TodoIcon.
  • Cada ícono, como completeIcon y deleteIcon, se ha convertido en un componente React dentro de esta librería.
  • La librería permite enviar propiedades dinámicas, como color, a los íconos para personalizar su apariencia.

Estilos y Separación de Responsabilidades

  • Hemos separado los estilos relacionados con los íconos en un archivo dedicado llamado todoitem.css para mejorar la organización.
  • Utilizamos clases como icon-container y icon-svg para aplicar estilos a los contenedores y los elementos SVG de los íconos, respectivamente.

Manejo de Eventos y Prop Drilling

  • Hemos abordado el desafío del “prop drilling” al pasar eventos a través de varios niveles de componentes.
  • Cada ícono ahora traduce sus eventos a una propiedad onClick para facilitar su manipulación en componentes superiores.

Interactividad Mejorada

  • La aplicación ahora permite completar y eliminar tareas con éxito.
  • Implementamos la lógica para cambiar dinámicamente los colores de los íconos según el estado de la tarea.

Próximos Pasos y Consideraciones

  • Aunque hemos logrado una interactividad significativa, aún quedan aspectos por abordar, como la creación de nuevas tareas.
  • También anticipamos el desafío de escalar la aplicación a medida que crece, lo que requerirá la adopción de prácticas y conceptos más avanzados en React.

En la próxima clase y módulo, exploraremos la creación de nuevas tareas y abordaremos estrategias avanzadas para manejar proyectos React más grandes y complejos. ¡Sigue aprendiendo y mejorando tus habilidades de desarrollo con React!

Así va quedando el mío

Así va mi app hasta ahora: ![](https://static.platzi.com/media/user_upload/preview-83938bcc-d544-48f6-8171-a9a2e6537be3.jpg) El repositorio: <https://github.com/julioribera/platzi-react>

Estoy tomando el curso para repasar conocimientos, y resulta que he aprendido varias cosa interesantes, excelente profesor

En mi caso no vi necesario crear dos componentes para cada icono, así que pase directo al componente TodoIcon que contiene la lógica. ```js function TodoItem(props) { return (
  • <TodoIcon color={props.completed ? 'green' : 'gray'} type='check' onClick={props.onCompleted} />

    {props.text}

    <TodoIcon color='gray' type='delete' onClick={props.onDelete} />
  • ); } ```

    viendo como juan trabaja como un pro haciendo su libreria, yo usando React Icons c: jajaja,

    <import './TodoItem.css';
    import { AiOutlineCheck } from 'react-icons/ai'
    import { BsFillTrash3Fill } from 'react-icons/bs'
    
    function TodoItem({completed,text,onComplete,onDelete}){
        return(
        <li className="TodoItem">
            <span 
            className={`Icon Icon-check ${completed&&"Icon-check--active"}`}
            onClick={onComplete}
            ><AiOutlineCheck/>
            </span>
    
            <p 
            className={`TodoItem-p ${completed&&"TodoItem-p--complete"}`}
            >{text}
            </p>
    
            <span 
            className="Icon Icon-delete"
            onClick={onDelete}
            ><BsFillTrash3Fill/>
            </span></li>);}
    export{TodoItem};> 
    

    Esta fue mi solucion

    import './TodoItem.css'
    import { CompleteIcon } from './CompleteIcon.js';
    import { DeleteIcon } from './DeleteIcon.js';
    
    function TodoItem({text, completed, onCompleted, onDelete}) {
      return (
        <li className={`TodoItem ${completed && "TodoItem__Completed"}`}>
          <button
            className='TodoItem__Container'
            onClick={onCompleted}
          >
          <CompleteIcon
            completed={completed}
          />
          
          </button>
          <p 
            onClick={onCompleted}
          >
            {text}
          </p>
          <button 
            className='TodoItem__Container'
            onClick={onDelete}
            >
          <DeleteIcon
            completed={completed}
          />
          </button>
        </li>
      );
    }
    
    export { TodoItem };
    
    

    👀DATO: Los icons de react-icons son como SVG asi que aplica perfectamente añadirles el atributo fill y jugar con él.

    min 4:38 “reducionales” jajajaj me hizo acordar que me quede en la clse de reducer en el curso de “manejo del estado” jejeje

    Desde mi perspectiva podría ser una solución quizás no muy escalable pero funcional y sin meternos tanto en clases de CSS, los iconos los exporte personalizados en Figma.

    function TodoItem(props) {
        if(props.completed === true){
            return(
                <div  className="item-container">
                <img src="../../public/Check.svg" alt="Icon" onClick={props.onComplete}/>
                <p>{props.text}</p>
                <img 
                src={'../../public/Delete.png'}
                alt="Icon"
                onClick={props.onDelete}/>
                </div>
            );
        }else{
            return(
                <div  className="item-container">
                <img src="../../public/Incompleto.svg" alt="Icon" onClick={props.onComplete}/>
                <p>{props.text}</p>
                <img 
                src={'../../public/Delete.png'}
                alt="Icon"
                onClick={props.onDelete}/>
                </div>
            );
        }
        
    }
    
    export {TodoItem}```
    

    Te equivocas en una letra y se rompe Q DESESPERACIÓN!!! JAJAJJA
    Tuve que leer mi código varias veces para corregirlo y que funcione

    Para entender clases como esta es que es sirve tomar apuntes de cada clase. Hagan bien su tarea muchachos, se van a agradecer a ustedes mismos!

    Muchachos recuerden que siempre hay varios caminos para llegar a lo mismo, en mi caso envolví el componente en un elemento que no modifica mucho como el div y en el div asigne una pequeña clase que me centra el componente, por último, asigne el evento al elemento que envuelve. Para ser más exacto analiza el código a continuación:

    Componente TodoItem.js

    import { CompleteIcon } from './CompleteIcon';
    import { DeleteIcon } from './DeleteIcon';
    import './TodoItem.css';
    
    function TodoItem ({text, completed, onComplete, onDelete}) {
      return( 
      <li className="TodoItem">
        {/*Elemento div quien ejecuta y envuelve */}
        <div onClick={onComplete}>
          <CompleteIcon 
            completed={completed}
          />
        </div>
        <p className={`TodoItem-p ${completed && "TodoItem-p--complete"}`}>
          {text}
        </p>
        <div onClick={onDelete}> 
          <DeleteIcon/>
        </div>
      </li>
    )
    }
    export {TodoItem};
    

    Estilos TodoItem.css

    .TodoItem div {
      display: grid;
      place-items: center;
    }
    

    Esto del prop drilling puede afectar a futuro en los proyectos. Aunque uno pensaría que podríamos usar librerías y listo.
    Pero que pasa si en un proyecto usan sus propios diseños, ahí si no podemos decirle adiós a sus diseños jajaja.

    Bueno, entender así como quien dice entender, no entendí xD pero lo importante es seguir y aquí sigo :D

    Esta facil, cuando pones atención

    Toda la movida con los iconos me parecio muy compleja unicamente importe desde react icons y los remplaze por el span y sigue sirviendo ![](https://static.platzi.com/media/user_upload/image-64980bbc-2c45-4254-8fd2-f64a00c34604.jpg) ![](https://static.platzi.com/media/user_upload/image-814131ea-b0dd-4514-9475-588be4ad6073.jpg)![]()
    ayweyyy mi mente !!!! ahh bastaaaa
    Tantas vueltas para un icono
    Si por casualidad quieren utilizar los iconos de react-icons y no saben como modificar los estilos dinamicamente, etc. En el repositorio de react-icons hay una parte donde pueden ver las modificaciones que se podrian usar utilizando "context" <https://github.com/react-icons/react-icons> ![](https://static.platzi.com/media/user_upload/image-80b2ce67-d229-4ff8-aae1-dbd7c7c6dc05.jpg)
    hola aqui un poco de props drilling (Spoiler una posible solucion es con useContext) <https://frontend.adaitw.org/docs/react/react23>
    Que está pasando con los recursos? , con la nueva interface no se ven los recursos.

    Esta clase necesita el 200% de concentración para poder comprenderse 🤣🤓

    Pero va genial

    Me encanto esto:

    iconTypes[type](color)
    "check": color => <CheckSVG className="Icon-svg" fill={color} />