1 of 12

React Context

Diseño para todys

2 of 12

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

3 of 12

El mecanismo state/prop puede ser incómodo

4 of 12

Context to the rescue

El Context actúa de memoria compartida entre los componentes.

Principal

1

2

1.1

1.1.1

5 of 12

Construyendo el Context

Es simplemente un objeto global que se construye con una función de React

export const Context = createContext()

6 of 12

Construyendo el Provider

  • Puede definir su propio estado
  • Y llamar a funciones que modifiquen ese estado
  • Ubicamos en la referencia value lo que queremos que sea público

export const Provider = ({ children }) => {

const [count, setCount] = useState(0)

const value = {

count,

increment: () => {

setCount(count + 1)

},

}

return (<Context.Provider value={value}>{children} </Context.Provider>)

7 of 12

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>

8 of 12

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>

9 of 12

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: () => {},

})

10 of 12

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')

})

11 of 12

Alternativas

  • Manejar el estado con state / props (en muchas aplicaciones con eso es suficiente)
  • Redux: una variante más compleja, que necesita de más conceptos (reducers, store, dispatch actions), tiene más herramientas de debugging y es ideal cuando tenés que trabajar con información que cambia permanentemente. Podés ver el siguiente artículo que explica cómo funciona (también podés descargar el ejemplo del contador en Redux).

12 of 12

¡Gracias!