Esto se veía muy feo
Introducción y requisitos
¿Qué necesitas para aprender React.js?
Maquetación con React.js
¿Qué es un componente?
Componentes de TODO Machine
¿Cómo se comunican los componentes? Props y atributos
Estilos CSS en React
Interacción con React.js
Eventos en React: onClick, onChange
¿Qué es el estado?
Contando TODOs
Buscando TODOs
Completando y eliminando TODOs
Librería de Iconos Personalizados
Iconos en React: librerías y SVG
Iconos con colores dinámicos
Herramientas avanzadas: escalabilidad, organización y persistencia
Local Storage con React.js
Custom Hooks
Organización de archivos y carpetas
Feature-First Directories en React
Tips para naming y abstracción de componentes React
¿Qué son los efectos en React?
Estados de carga y error
Actualizando estados desde useEffect
Reto: loading skeletons
¿Qué es React Context?
useContext
¿Qué son los React Portals?
Reto: estados para abrir y cerrar un modal
Maquetando formularios en React
Crear TODOs: React Context dentro de React Portals
Deploy
Despliegue de TODO Machine en GitHub Pages
Presentación de proyectos para tu portafolio
Próximos pasos: React #UnderTheHood
Diferencias entre versiones de React.js
¿Cuándo realmente necesitas React.js?
Bonus: creando proyectos en React desde cero
React con Create React App
React con Next.js
React con Vite
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Juan David Castro Gallego
Aportes 39
Preguntas 8
Esto se veía muy feo
Así lo hice con React Icons:
Primero instalé react Icons
npm install react-icons --save
despues hice el componente DeleteIcon.js.
despues hice el componente CompleteIcon.js.
despues modifiqué el TodoItem.js
y en el css de TodoItem.css
eso es todo. la cuestion es que no sé que tan válido sea.
Para los que lo estan haciendo con la libreria de
react-icons
les recomiendo no usar el archivo TodoIcons.js, aumenta la complejidad del codigo. En lugar de eso creen los componentes de cada icono por separado y usenlos directamente sobre su componente TodoItem de esta manera
CompleteTodo.js
import React from 'react'
import {RxCheck} from 'react-icons/rx'
const CompleteIcon = (props) => {
const {className, onClick} = props
return (
<RxCheck
className={className}
onClick={onClick}
/>
)
}
export {CompleteIcon}
DeleteTodo.js
import React from 'react'
import {RxCross1} from 'react-icons/rx'
const DeleteIcon = (props) => {
const {className, onClick} = props
return (
<RxCross1
className={className}
onClick={onClick}
/>
)
}
export {DeleteIcon}
TodoItem
import React from "react";
import "../styles/TodoItem.css";
import { CompleteIcon } from "./CompleteIcon";
import { DeleteIcon } from "./DeleteIcon";
const TodoItem = (props) => {
const { text, completed, onToggle, onDelete } = props;
return (
<li className="TodoItem">
<div className={`check-container ${completed && "completed"}`}>
<CompleteIcon
className={`check ${completed && "completed"}`}
onClick={onToggle}
/>
</div>
<p className={`todo ${completed && "completed"}`}>{text}</p>
<div className="closer-container">
<DeleteIcon className="closer" onClick={onDelete} />
</div>
</li>
);
};
export { TodoItem };
solucionen los problemas que tienen con la carga de las clases, es imposible estudiar y entender un concepto si cada minuto y medio se pausa la clase y tengo que esperar otros tres minutos para que cargue. Paso una hora con cada clase
Hasta ahora sigo usando la versión gratuita de FontAwesome. Por ahora, funciona como debe funcionar.
npm i @fortawesome/fontawesome-svg-core
npm i @fortawesome/free-regular-svg-icons
npm i @fortawesome/free-solid-svg-icons
npm i @fortawesome/react-fontawesome
{props.text}
<BsFillXCircleFill />{props.text}\
\<span className="Icon Icon-delete" onClick={props.onDelete} > \<BsFillXCircleFill /> \ \Quedé un poco perdido en cómo se estaba haciendo antes pero lo probé de esta manera y quisiera compartirlo 😄
TodoItem.js
import './TodoItem.css';
import { DeleteIcon } from "./DeleteIcon";
import { CompleteIcon } from "./CompleteIcon";
function TodoItem(props) {
return (
<li className="TodoItem">
<CompleteIcon completed={props.completed} onComplete={props.onComplete} />
<p className={`TodoItem-p ${props.completed && "TodoItem-p-completed"}`}>{props.text}</p>
<DeleteIcon onDelete={props.onDelete} />
</li>
);
}
export { TodoItem };
A continuación CompleteIcon.js
import { GiChainedArrowHeads } from "react-icons/gi";
import React from 'react'
export const CompleteIcon = (props) => {
return (
<GiChainedArrowHeads
className={`Icon Icon-check ${props.completed && "Icon-check--active"}`}
onClick={props.onComplete}
/>
)
}
A continuación DeleteIcon.js
import React from 'react'
import {GiAnticlockwiseRotation} from "react-icons/gi";
export const DeleteIcon = (props) => {
return (
<GiAnticlockwiseRotation
className={"Icon Icon-delete"}
onClick={props.onDelete}
/>
)
}
Para los que no pudieron usar los icons aqui les dejo una lista de lo que podrian hacer para usar los iconos de la pagina “React icons”
Paso 1. Instala React Icons
Si aun no lo has hecho, instala React Icons en tu proyecto
npm install react-icons
import React from 'react';
import { CiAlignCenterH } from "react-icons/ci";
<p><span><CiAlignCenterH/></span></p>
Espero te pueda servir…!!!
Yo lo pude hacer de otra manera:
function TodoIcon({ type }) {
return (
<span className={Icon Icon-svg Icon-${type}
}
>
{type === ‘check’ && <Check />}
{type === ‘delete’ && <Delete />}
</span>
);
}
Bueno revisando los comentarios y lo aprendido en clase logré ambos usos uno con el svg local y otro importando la libreria de react:
npm install react-icons --save
el TodoItem.js
import { DeleteIcon } from './DeleteIcon'
import { CheckIcon } from './CheckIcon'
import './TodoItem.css'
function TodoItem (props) {
return(
<li className="TodoItem">
<label>
<CheckIcon
completed={props.completed}
onClick={props.onComplete}
/>
<p
className={`TodoItem-p ${props.completed ? 'TodoItem-p--complete' : ''}`}>
{props.text}
</p>
</label>
<DeleteIcon
onClick = {props.onDelete}
/>
</li>
);
}
export { TodoItem };
el TodoIcon.js:
import { ReactComponent as DeleteSVG } from './quit.svg';
import { BsClipboardCheck } from 'react-icons/bs';
const iconTypes = {
"check": <BsClipboardCheck />,
"delete": <DeleteSVG />,
};
function TodoIcon({ type , onClick , completed}) {
return (
<span
className={`Icon Icon-${type} ${completed ? `Icon-${type}--active` : ''}`}
onClick = {onClick}
>
{iconTypes[type]}
</span>
)
}
export { TodoIcon };
el CheckIcon.js
import React from 'react';
import { TodoIcon } from './TodoIcon'
function CheckIcon({ completed, onClick}) {
return (
<TodoIcon
type="check"
color="gray"
completed = {completed}
onClick={onClick}
/>
);
}
export { CheckIcon };
y el que vimos en clase DeleteIcon.js
import React from 'react';
import { TodoIcon } from './TodoIcon'
function DeleteIcon({onClick}) {
return (
<TodoIcon
type="delete"
color="gray"
onClick={onClick}
/>
);
}
export { DeleteIcon };
Espero les sirva un poco
Cuando vayas a importar un useEffect, useState, useRef no hagas esto:
import React, { useEffect, useState } from "react";
Mejor déjalo así:
import { useEffect, useState } from "react";
Que se quitó, pues, el React. Porque agregar este mismo es redundante.
En esta sección, nos enfocaremos en personalizar íconos en ReactJS para mejorar la apariencia de nuestra aplicación. Utilizaremos una librería de íconos llamada React Icons, aunque también exploraremos cómo crear nuestra propia librería de íconos para íconos personalizados. A continuación, detallamos los pasos:
check.svg
y delete.svg
.todoicon.js
):
CompleteIcon
y DeleteIcon
:
CompleteIcon.js
y DeleteIcon.js
) que importan íconos personalizados y especifican el tipo y el color.type
decide qué ícono renderizar, y las clases de estilo (icon-check
o icon-delete
) gestionan su posición.CompleteIcon
y DeleteIcon
en la aplicación principal.type
y color
para personalizar la apariencia de los íconos según las necesidades del proyecto.Este enfoque en la personalización de íconos proporciona flexibilidad y control sobre la apariencia de la aplicación, permitiendo adaptarse a los requisitos específicos del proyecto.
🙃 Los que estén oscuros sobre SVG, entren acá. 🙂
Si son muchos pasos para ti, considera instalar react-icons o usa otras librerías como font-awesome, boxicons, con estas librerias si deseas que sea aún más fácil, solo uso el CDN, que estos proporcionan.
La solucion aburrida:
import "./TaskItem.css";
import "../ButtonClose/ButtonClose.css";
function TaskItem(props) {
return (
<li className="TaskItem">
<span className="TaskItem-Icon" onClick={props.onComplete}>
{props.done === true ? "✅" : "⬜"}{" "}
</span>
<p
className={`TaskItem-Task ${
props.done ? " TaskItem-Task--complete" : ""
}`}
>
{props.title}
</p>
<button type="button" className="ButtonClose" onClick={props.onRemove}>
x
</button>{" "}
</li>
);
}
export default TaskItem;
From: Rincon del vago
Así lo hice
Cambiando los iconos, es otra cosa
por saltarme las dos clases de como trabajar con SVGs me tuve que regresar desde el curso react-reuter donde agregan el svg de editar jajajaj
Para desmarcar las completadas sin tanto codigo!!
const completeTodo = (text) => {
const newTodo = […toDo];
const toDoIndex = newTodo.findIndex(
(todo) => todo.text == text
);
newTodo[toDoIndex].completed = !newTodo[toDoIndex].completed;
setTodo(newTodo);
}
En mi caso lo había hecho de esta forma, utilizando operadores ternarios para asignarles las clases a mis button y de esa forma poder estilar los icons, ¿debería cambiar el código?
import {PiCheckFatFill} from "react-icons/pi";
import {ImCross} from "react-icons/im"
import './ToDoItem.css';
function ToDoItem({text, completed, onComplete, onDelete}) {
const iconCheked = completed ? 'item-button item-button-check--active' : `item-button item-button-check`;
const iconDelete = completed ? 'item-button item-button-delete-check--active' : `item-button item-button-delete`;
return(
<li className={`item-li ${completed && "item-li-completed"}`}>
<span className='item-span'>
<div className='item-container-button-check'>
<button className={iconCheked}
onClick={onComplete}><PiCheckFatFill /> </button>
</div>
<p className={`item-p ${completed && "item-p--active"}`}>
{text}
</p>
</span>
<span>
<div className='item-container-button-delete'>
<button className={iconDelete} onClick={onDelete}>
<ImCross />
</button>
</div>
</span>
</li>
);
}
export {ToDoItem}
.item-container-button-check {
height: auto;
width: auto;
display: flex;
justify-content: center;
align-items: center;
}
.item-button {
height: 20px;
width: auto;
padding: 0;
font-size: 22px;
background-color: transparent;
border: none;
}
.item-button:hover {
cursor: pointer;
}
.item-button-check {
color: #5fa01d;
}
.item-button-check:hover {
color: #2c2c2c;;
}
.item-button-delete {
font-size: 18px;
color: #fc3a51;
}
.item-button-delete:hover {
opacity: 0.7;
}
.item-button-check--active {
color: #2c2c2c;
}
.item-button-delete-check--active {
color: #2c2c2c;
font-size: 18px;
}```
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?