No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Reg铆strate

Comienza en:

3D
21H
52M
35S

useLocation: transferencia de datos por navegaci贸n

24/30
Recursos

Aportes 10

Preguntas 1

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Esta ser铆a mi respuesta al retor, cualquier sugerencia estar茅 pendiente:

React router v6

React router v5

Toca ver varias veces esta clase馃馃お

Para resolver el reto del minuto 13:22, le铆 la documentaci贸n del hook useNavigate() de React Router, y not茅 que la funci贸n navigate() no s贸lo recibe una ruta, sino tambi茅n un objeto de opciones:

Y entre las opciones recibe la propiedad state, entonces desde el HomePage, agregu茅 el objeto de opciones con la propiedad state a la funci贸n navigate(), asign谩ndole como valor al state el texto del TODO de cada TodoItem que est谩 siendo mapeado por el TodoList.

Luego en la p谩gina EditTodoPage, por medio del hook useLocation(), le asign茅 el valor del state a la propiedad defaultTodoText del componente TodoForm.

Y listo, de esta forma podemos enviar directamente el texto de cada TODO al formulario TodoForm sin necesidad de esperar los segundos para que carge el localStorage.

Yo he encontrado un error.
.
Resulta que la aplicaci贸n cada vez que damos click en los botones de a帽adir un TODO o editar un TODO, hace uso del custom hook useTodos() y este a su vez hace uso del custom hook useLocalStorage() (y como sabemos este es s铆ncrono, requiere de tiempo).
.
Entonces cada vez que accedemos a las rutas /new o /edit/ debemos esperar que carguen los todos del localStorage nuevamente porque los necesitamos para las funciones addTodo() y editTodo() y aqu铆 es donde est谩 el problema.
.
Si modificamos el setTimeout() de useLocalStorage() a 5 segundos por ejemplo y luego accedemos a /new o /edit y agregamos o editamos informaci贸n antes de que pasen 5 segundos habr谩 problemas.

  • En el caso de addTodo() se sobrescribir谩 la informaci贸n, porque la constante newTodos va a ser igual a un arreglo vac铆o.
  • En el caso de editTodo() se romper谩 la aplicaci贸n, porque la constante todoIndex va a ser -1.

.
Para solucionar esto lo que hice fue deshabilitar el <textarea> y el bot贸n de A帽adir/Editar usando el state loading de useTodos()

  • En newTodoPage() y EditTodoPage() agregue lo siguiente:
//use el loading y se lo pase al <TodoForm />
const { editTodo, getTodo, loading } = useTodos()

return (
	<TodoForm
		loading={loading}
		...
		...
)

  • En TodoForm() agregue lo siguiente:
function TodoForm(props) {
	...
	...

	return (
		...
		<textarea 
			disabled={props.loading}
			...
		/>
		<button
			disabled={props.loading}
		>
			{props.submitText}
		</button>
	)
}

Previamente, hab铆a publicado un c贸digo que ten铆a dos errores:

  • al entrar directamente a una url, state (location) no exist铆a y tiraba un error.
  • si el id del to-do no exist铆a, saltaba un error

Ya correg铆 esos errores, dejo el nuevo c贸digo abajo.

App.js

<Route path="/edit/:id" element={<EditTodoPage />} />

EditTodoPage.js

export function EditTodoPage() {
    const { editToDo, loading, getToDo } = useToDos()
    const { state } = useLocation()
    let { id } = useParams()
    id = Number(id) //useParams converts number to text. Just in case, it is converted to number again

    let toDoText

    if (!state) {
        if (loading) return <p>loading</p>
        let toDo = getToDo(id)
        if (!toDo) return <NotFound />
        toDoText = toDo.text
    } else ({ toDoText } = state)

    return (
        <TodoForm
            submitEvent={newText => editToDo({ id, newText })}
            title="Edit To-Do"
            submitText="Edit"
            defaultText={toDoText}
        />
    )
}

Pens茅 que iba a poder con este reto, pero una vez m谩s encontr茅 varias formas de Como no hacerlo鈥D.
Aprend铆 que useLocation es inmutable.

Juan dice que esta clase fue d铆ficil鈥
Para m铆 lo fue, pero por ese bendito loading que me hizo estar debuggeando un buen rato! 馃樀

Me estaba sucediendo un error, muestro screenshot:

.
Y suced铆a porque me sal铆a del NewPage hacia el HomePage sin que terminar谩n de cargar los todos, as铆 que, cuando ya hab铆an cargado y el estado loading cambia a true, el componente TodoForm ya est谩 desmontado, y ocasiona el error.
.
La soluci贸n a esto es DETENER la carga de los todos al salirnos del NewPage (y EditPage tambi茅n). C贸mo hacemos eso?
.
En efecto, como nos dice el error, debemos cancelar esa carga de todos desde una Cleanup Function en nuestro useEffect que genera el setTimeout dentro de useLocalStorage. Esto es lo equivalente a un willUnmount del antiguo React.

React.useEffect(() => {
		const timeout = setTimeout(() => {
			try {
				const localStorageItem = localStorage.getItem(itemName);
				let parsedItem;

				if (!localStorageItem) {
					localStorage.setItem(itemName, JSON.stringify(initialValue));
					parsedItem = initialValue;
				} else {
					parsedItem = JSON.parse(localStorageItem);
				}

				onSuccess(parsedItem);
			} catch (error) {
				onError(error);
			}
		}, 3000);

		//CLEANUP FUNCTION
		return () => {
			clearInterval(timeout);
		};
	}, [sincronizedItem]);

Yo me propuse lograr la funcionalidad antes de ver el video de esta clase, les comparto mi soluci贸n:

  • Primero edit茅 la propiedad path de la etiqueta Route que nos lleva al componente EditTodoPage para que aceptara un par谩metro m谩s:
  • Luego le agreg茅 a la funci贸n navigate de onEdit el par谩metro todo.text
  • Y por 煤ltimo defin铆 ese texto como valor por defecto de newTodoValue en el componente TodoForm 馃槂

    Y listo 馃槂

鈥渟i, cambio un poquito el navegador鈥 jajajajaj