umm, mi lado radical eliminó todo lo que tenía delineado amarillo, pero mi lado prudente hizo commit antes de eso.
Fundamentos de navegación en la web
¿Cuándo necesitas React Router?
SSR vs. Single Page Applications
Versiones de React Router: ¿Por qué son tantas? ¿Cuál elegir?
Introducción a React Router DOM 6
Instalación de React Router DOM 6
BrowserRouter vs. HashRouter
Route: componentes de navegación
Link vs. NavLink
useParams: rutas dinámicas
useNavigate: historial de navegación
Outlet: nested routes
Fake authentication con React Router DOM 6
useAuth: login y logout
Menú con rutas públicas y privadas
Navigate y redirects: protegiendo rutas privadas
Roles y permisos
Reto: composición de componentes con navegación
Reto: UX de login y logout
Reto: roles complejos
React Router en TODO Machine
Integrando React Router a proyectos en React
Creando las rutas de TODO Machine
Botón de editar TODOs
Generador automático de IDs
Cambiando modales por navegación
Obtener y editar TODOs
useLocation: transferencia de datos por navegación
Deploy con React Router en GitHub Pages
Próximos pasos
Reto: página de búsquedas con navegación
Reto: TODO Machine con React Router DOM 5
Reto: PlatziMovies con React Router
Reto: crea tu propio React Router
Espera más cursos de React.js
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Juan David Castro Gallego
Aportes 10
Preguntas 3
umm, mi lado radical eliminó todo lo que tenía delineado amarillo, pero mi lado prudente hizo commit antes de eso.
👀 Yo cree un div que encierre o agrupe el formulario para poder centrarlo, ya que si lo hacemos de la forma normal con el margin auto, en responsive se rompe un poco la ui
const NewPage = () => {
return (
<div className='new-todo-container'>
<TodoForm
title="Write your new TODO"
submitText="Add"
submitEvent={() => console.log('llamar a add todo')}
/>
</div>
)
}
Y el css
.new-todo-container{
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
Espero les sirva.
Saludos.
Una alternativa a la funcionalidad creada en la clase para los textos dinamicos, es usar el hook de React Router DOM ‘useLocation’ que devuelve la ruta actualmente usada y con esto hacer la validación necesaria.
Creo que así, nos evitamos el tener que mandar props adicionales.
const location = useLocation();
<label>{(location.pathname === '/new') ? 'Escribe tu TODO' : 'Edita tu TODO'}</label>
Yo el botón de CreateTodo lo cambiaría por un componente Link.
Esto dice la documentación 👇:
Además, un componente Link es una etiqueta <a href=""> por detrás, lo cual es necesario para tener un buen SEO.
.
Es el equivalente a usar un <button> en vez de un <a> para cambiar de URLs en HTML puro.
Estaba pensando otra manera que se podría hacer es que al agregar tareas, en lugar de navegar a una página de Edit o New Todo, se añada un nuevo input al final de los todos y deshabilitar su uso modificación hasta que se haga click en Edit.
Me pasó que justo cuando hice los cambios con el profe no tenía TODOS para confirmar si lo que hice estaba bien, así que tuve que hacer por adelantado el añadir TODOS (Aunque no sé si es la mejor forma, me funcionó)
import React from "react";
import { TodoForm } from "../../ui/TodoForm";
import { useTodos } from "../useTodos";
function NewTodoPage() {
const { stateUpdaters } = useTodos();
const { addTodo } = stateUpdaters;
return(
<TodoForm
label="Escribe tu nuevo TO DO"
submit="Añadir"
submitEvent={addTodo}
/>
)
}
export { NewTodoPage }
Hola papus, dejo el codigo de la clase en TS:
import { FC, FormEvent, useState } from "react"
import { useLocation, useNavigate } from "react-router-dom";
import './TodoForm.css'
interface Props {
submitEvent: (v:string)=>void,
}
const TodoForm:FC<Props> = ({ submitEvent }) =>{
const navigate = useNavigate();
const location = useLocation();
const [newTodoText, setNewTodoText] = useState('');
const onCancel = ()=>{
navigate('/');
}
const onSubmit = (e:FormEvent<HTMLFormElement>) => {
e.preventDefault();
submitEvent(newTodoText);
navigate('/');
}
return(
<form onSubmit={onSubmit}>
<label>{location.pathname === '/new'? 'Escribe tu nueva tarea pendiente':'Edita tu tarea pendiente'}</label>
<textarea
placeholder="Hola, que haremos hoy?"
value={newTodoText}
onChange={(event)=>{
setNewTodoText(event.target.value)
}}
/>
<div className="TodoForm-buttonContainer">
<button
type="button"
onClick={onCancel}
className="TodoForm-button TodoForm-button--cancel"
>
Cancelar
</button>
<button
type="submit"
className="TodoForm-button TodoForm-button--add"
>
{location.pathname === '/new'? 'Añadir':'Editar'}
</button>
</div>
</form>
)
}
export { TodoForm }
sería bueno haber dejado el modal como para no perder la funcionalidad de los portales y hacer el edit en una nueva ventana
.
Vamos a eliminar los modales y portales de la aplicación para utilizar rutas en su lugar.
.
En el componente HomePage
comentamos todo lo relacionado a modales y portales, importamos useNavigate
y guardamos su llamado en una constante navigate
.
.
Al renderizar los todos en la render prop onEdit
usamos la navegación para dirigirnos a /edit/:id
donde id
será el ID del TODO.
.
Finalmente, el botón de crear TODOs recibirá una función flecha que por medio de navegación nos dirige a /new
.
.
...
import { useNavigate } from 'react-router-dom';
...
function HomePage() {
const navigate = useNavigate();
...
const {
...
// openModal,
...
} = state;
const {
// setOpenModal,
// addTodo,
...
} = stateUpdaters;
return (
...
{todo => (
<TodoItem
key={todo.id}
text={todo.text}
completed={todo.completed}
onEdit={() => navigate('/edit/' + todo.id)}
onComplete={() => completeTodo(todo.id)}
onDelete={() => deleteTodo(todo.id)}
/>
)}
...
{/* {!!openModal && (
<Modal>
<TodoForm
addTodo={addTodo}
setOpenModal={setOpenModal}
/>
</Modal>
)} */}
<CreateTodoButton
onClick={() => navigate('/new')}
// setOpenModal={setOpenModal}
/>
...
);
}
export { HomePage };
.
En el componente CreateTodoButton
ya no necesitamos modales, por lo que solo le enviamos la función que pasamos por props a la propiedad onClick
.
.
import React from 'react';
import './CreateTodoButton.css';
function CreateTodoButton(props) {
return (
<button
className="CreateTodoButton"
onClick={props.onClick}
>
+
</button>
);
}
export { CreateTodoButton };
.
En el componente TodoForm
necesitamos que sea dinámico, tanto para editar, como para crear TODOs.
.
Lo que cambia es que ahora utilizamos navegación tanto para el botón de Cancelar
como para el botón para realizar el Submit
, vamos redirigir hacia /
. Además nuestra función onSubmit
va a utilizar una función que pasaremos por props submitEvent
que será versátil para crear o editar TODOs según sea el caso.
.
Finalmente, tanto el label
como el texto del botón de submit
van a ser dinámicos y los pasaremos por props.
.
...
import { useNavigate } from 'react-router-dom';
...
function TodoForm(props) {
const navigate = useNavigate();
...
const onCancel = () => {
navigate('/');
};
const onSubmit = (event) => {
event.preventDefault();
navigate('/');
props.submitEvent(newTodoValue);
};
return (
<form onSubmit={onSubmit}>
<label>{props.label}</label>
<textarea
value={newTodoValue}
onChange={onChange}
placeholder="Cortar la cebolla oara el almuerzo"
/>
<div className="TodoForm-buttonContainer">
<button
type="button"
className="TodoForm-button TodoForm-button--cancel"
onClick={onCancel}
>
Cancelar
</button>
<button
type="submit"
className="TodoForm-button TodoForm-button--add"
>
{props.submitText}
</button>
</div>
</form>
);
}
export { TodoForm };
.
Desde el archivo TodoForm.css
centramos el componente y le quitamos el color de fondo que tenía en la clase form
.
.
form {
width: 90%;
max-width: 300px;
/* background-color: #fff; */
margin: 0 auto;
padding: 33px 40px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.
Por último, solo que modificar los componentes de EditTodoPage
y NewTodoPage
de la siguiente manera.
.
import React from 'react';
import { TodoForm } from '../../ui/TodoForm';
function EditTodoPage() {
return (
<TodoForm
label="Edita tu TODO"
submitText="Editar"
submitEvent={() => console.log('Llamar a editTodo')}
/>
);
}
export { EditTodoPage };
import React from 'react';
import { TodoForm } from '../../ui/TodoForm';
function NewTodoPage() {
return (
<TodoForm
label="Escribe tu nuevo TODO"
submitText="Añadir"
submitEvent={() => console.log('Llamar a addTodo')}
/>
);
}
export { NewTodoPage };
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?