React Context
Diseño para todys
El mecanismo state/prop puede ser incómodo
Si tenemos una jerarquía extensa de componentes debemos pasar el state como prop y además una función que cambie el estado en el componente principal.
Principal
1
2
1.1
1.1.1
recibe como props el estado y la función para modificar el estado
El mecanismo state/prop puede ser incómodo
Context to the rescue
El Context actúa de memoria compartida entre los componentes.
Principal
1
2
1.1
1.1.1
Construyendo el Context
Es simplemente un objeto global que se construye con una función de React
export const Context = createContext()
Construyendo el Provider
export const Provider = ({ children }) => {
const [count, setCount] = useState(0)
const value = {
count,
increment: () => {
setCount(count + 1)
},
}
return (<Context.Provider value={value}>{children} </Context.Provider>)
Nuestros componentes son hijos del Provider
Recordemos que el Provider se define como un componente que espera children en sus props. Así que lo que hacemos es decorar nuestros componentes principales con el provider:
import { Provider } from './context/Context'
const App = () =>
<Provider>
<Contador />
<LogContador />
</Provider>
Y consumen estado y funciones del context
El hook useContext nos da la posibilidad de obtener una referencia al estado + las funciones para manipular ese estado.
const Contador = () => {
const { count, decrement, increment } =
useContext(Context)
...
<Button primary
onClick={decrement}>-</Button>
createContext permite pasarle valores por defecto
Podemos ver qué pasa si Contador está por afuera del Provider que definimos:
const App = () =>
<>
<Contador />
<Provider>
<LogContador />
</Provider>
</>
export const Context = createContext({
count: 20,
increment: () => {
console.info('hola')
},
decrement: () => {},
})
Testeo de frontend
Para utilizar el contexto en los tests solo debemos utilizar el componente que trabaja con el Provider:
test('si se presiona el botón +, el contador pasa a estar en 1', () => {
render(
<App />
)
fireEvent.click(screen.getByTestId('button_plus'))
expect(screen.getByTestId('contador')).toHaveTextContent('1')
})
Alternativas
¡Gracias!