Al principio me pareció un poco confuso usar TodoContext.Provider, con useContext() es muchisimo más sencillo y legible!
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
No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Juan David Castro Gallego
Aportes 29
Preguntas 9
Al principio me pareció un poco confuso usar TodoContext.Provider, con useContext() es muchisimo más sencillo y legible!
Según la documentación nueva oficial de React, manifiestan que no es recomendado usar Consumer y que poco a poco empezara a entrar en desuso, Entonces viva, useContext.
Cuando necesitamos pasar los datos establecidos en el Context:
function TodoProvider({children}){
// Funcionalidades del provider
return (
<TodoContext.Provider>
{children}
</TodoContext.Provider>
)
}
La principal diferencia es el uso de TodoContext.Consumer dentro del componente que queramos comunicar con las props. Y el metodo por useContext que no implica pasar como si fuera un componente la sintaxis del Consumer.
<TodoContext.Consumer>
{
({ props necesarias }) => { // Todos los componentes para pasar las props }
}
</TodoContext.Consumer>
const { props necesarias } = useContext(TodoContext)
Gracias a esa explicacion de la clase Que es React Context, ahora tiene sentido como se trae el contexto con el hook useContext.
Bueno pues en el momento de las clases anteriores donde el profe creo el componente AppUI
, pues yo preferi no hacerlo y segui con el app normal metiendo todo ahi.
Esto me llevo a un pequeño problema al querer recrear lo que el profesor hizo en el video.
No podemos usar el
provider
en el mismo lugar donde vamos a usar eluseContext
.
Me toco ponerlo en elindex.js
para que luego en el componenteApp
me permitiera usar el use context.
Si le dejaba el provider ahi, pues se rompia todo
Asi que lo elimine de ahi y le deje las <>...</>
y ya.
Por si a alguien mas le pasa, pues nada ese es el motivo que no funcione bien
Les comparto una forma en la que me parece interesante exportar nuestros contexts. Esto sería creando nuestro propio hook para dicho context así:
// useStateContext.js
import React, { createContext, useContext } from "react";
const Context = createContext();
export const StateContext = ({ children }) => {
// ... Toda nuestra lógica
return (
<Context.Provider value={{
// ... Nuestros valores a exportar
}}>
{children}
</Context.Provider>
);
}
export const useStateContext = () => useContext(Context);
Como puedes ver, así exportaríamos nuestro StateContext y nuestro useStateContext, el cual ya utiliza el useContext; de esta forma, en los componentes podremos importarlos así:
// TuComponente.js
import { useStateContext } from '../Context/useStateContext';
function TuComponente() {
const {...tus valores a importar} = useStateContext();
return(
<></>
);
}
Así ya no tendremos que estarle indicando qué contexto queremos usar. Y en caso de tener varios contextos como nos enseña Juan, por ejemplo tener uno para los usuarios, otro para validaciones, ordenes… sería tan sencillo como importar dicho contexto y llamarlos como useUserContext(), useValidationContext(), useOrderContext()… según corresponda. 😀
Desde la clase anterior cuando implementamos Context mi app se murió 😦
Crea tu primer Todo
} {((!loading && searchTodos == 0 && totalToDos > 0)) &&No hay coincidencias
} ```import { Contexto } from ‘./direccionContexto/’
const { value } = React.useContext(Contexto)
useContext acepta un objeto de contexto (el valor devuelto de React.createContext) y devuelve el valor de contexto actual. El valor actual del contexto es determinado por la propiedad value del <MyContext.Provider> ascendentemente más cercano en el árbol al componente que hace la llamada.
Super cool, no conocía esto. Antes usaba solo Redux
UYY que bueno, mucho más limpio y fácil!!!
React.useContext god
Muy Bueno la combinación de TodoContext y el useContext.
El TodoContex nos permite exponer parametros de manera general en el app mediante el TodoContext.provider. Y mediante el TodoContext.consumer recuperamos los parametros expuestos pero esto resulta algo que ensucia el codigo, es por ello que usamos el hook useConext.
Si alguna vez les llega a salir este error
Me sale este error “TypeError: render is not a function”
Ese error se da ya que posiblemente en tu app() en el componente estas llamando al Context, lo que tienes que hacer es llamar a la funcion y no al Context
De la siguiente manera:
functionApp() {
return (
<TodoContext>
<AppUI/>
</TodoContext>
);
}
en esta linea de codigo lo que estas llamando es el Context en general y sino estoy mal lo que esta haciendo es renderizando por lo tanto sale el error, lo mas recomendable es crear una funcion en donde podamos tener toda la parte de los componentes y la logica en esa funcion
Dicho esto deberia quedar el codigo en la clase App asi:
//Esta funcion es un componente
functionApp() {
return (
<TodoProvider>
<AppUI/>
</TodoProvider>
);
}
El <TodoProvider> hace referencia al nombre de mi función
Proyecto en codigo TS:
import { FC, useContext } from "react";
import { TodoContext } from "../TodoContext";
import './TodoCounter.css'
const TodoCounter:FC = () => {
const {
completedTodos,
totalTodos
} = useContext(TodoContext)
return (
<h1 className="TodoCounter">Has completado <span>{completedTodos}</span> de <span>{totalTodos}</span></h1>
)
}
export { TodoCounter }
import { FC, useContext } from "react";
import { TodoContext } from "../TodoContext";
import './TodoSearch.css'
const TodoSearch:FC = () => {
const {
searchValue,
setSearchValue
} = useContext(TodoContext)
return (
<input
type="text"
className="TodoSearch"
placeholder="Ingresar nombre de tarea buscada"
value={searchValue}
onChange={(event)=>{
setSearchValue(event.target.value)
}}
/>
)
}
export { TodoSearch }
import { FC, useContext } from "react"
import { TodoButton } from "../TodoButton"
import { TodoCounter } from "../TodoCounter"
import { TodoItem } from "../TodoItem"
import { TodoList } from "../TodoList"
import { TodoSearch } from "../TodoSearch"
import { TodosError } from "../TodoError"
import { EmptyTodos } from "../EmptyTodo"
import { TodosLoading } from "../TodoLoading"
import { TodoContext } from "../TodoContext"
export const AppUI:FC = () => {
const {
loading,
error,
searchedTodos,
completeTodo,
deleteTodo,
} = useContext(TodoContext);
return (
<>
<TodoCounter />
<TodoSearch />
<TodoList>
{loading && (
<>
<TodosLoading />
<TodosLoading />
<TodosLoading />
</>
)}
{error && <TodosError />}
{(!loading && searchedTodos.length === 0) && <EmptyTodos />}
{
searchedTodos.map(todo=>(
<TodoItem
key={todo.text}
text={todo.text}
completed={todo.completed}
onComplete={()=>{completeTodo(todo.text)}}
onDelete={()=>{deleteTodo(todo.text)}}
/>
))
}
</TodoList>
<TodoButton />
</>
)
}
ME ENCANTO ESTA CLASE!
Crea tu primer Todo
} {((!loading && searchTodos == 0)) &&No hay coincidencias
```Un dato importante que pude observar. Para el caso de no utilizar useContext() dentro de un componente, este ultimo envuelto por un provider. No se renderiza dicho componente en caso cambie algún estado del hook context. Al inicio pensé que se renderizaría por estar envuelto por el provider.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?