Usar React context de forma correcta
Tags: react, tutorial, javascript, beginners
Published: 2022-09-13 07:51:38

El objetivo es extraer la lógica del `context` y asi no ensuciar nuestros componentes y ofrecer una forma sencilla de acceder a la información y modificarla.

Para este ejemplo vamos a crear un contador en un nuestro `context`. Para ello creamos un archivo `counter.context.jsx`.

```jsx
export const CounterContext = createContext();

export const CounterProvider = ({children}) => {
    const [counter, setCounter] = useState(0);

    return <CounterContext.Provider value={{counter, setCounter}}>
        {children}
    </CounterContext.Provider>
}
```

> Documentación oficial: [https://reactjs.org/docs/context.html](https://reactjs.org/docs/context.html)

Una vez tenemos creado nuestro contexto, en este mismo archivo vamos a crear un `useCounterContext` para poder modificar y acceder a la información de nuestro contexto.

```jsx
export const useCounterContext = () => {
    const context = useContext(CounterContext);

    if (context === undefined) {
        throw new Error('useCounterContext has to be used within a CounterProvider')
    }

    return context;
}
```

Si observamos, estamos comprobando que nuestro `context` no sea `undefined`. Esto ocurrirá cuando intentemos usar nuestro `useCounterContext` desde algún componente fuera de nuestro `CounterProvider`. Dicho esto vamos a observar como hacemos que el `useCounterContext` sea accesible a nuestros componentes encapsulando los componentes con nuestro `<CounterProvider />`.

```jsx
function App() {
    return (
        <div className="App">
            <h1>How to use React context</h1>
            <div className="card">
                <CounterProvider>
                    <FirstComponent/>
                    <SecondComponent/>
                </CounterProvider>
            </div>
        </div>
    )
}

export default App
```

Nuestro `counter.context.jsx` quedaría asi:

```jsx
export const CounterContext = createContext();

export const CounterProvider = ({children}) => {
    const [counter, setCounter] = useState(0);

    return <CounterContext.Provider value={{counter, setCounter}}>
        {children}
    </CounterContext.Provider>
}

export const useCounterContext = () => {
    const context = useContext(CounterContext);

    if (context === undefined) {
        throw new Error('useCounterContext has to be used within a CounterProvider')
    }

    return context;
}
```

Una vez echo esto, podemos acceder a los datos desde nuestros componentes `FirstComponent` y `SecondComponent`.

En nuestro `FirstComponent` vamos a modificar el `counter`, por medio del `setCounter` que nos facilita el `useCounterContext` que hemos creado previamente.

```jsx
function FirstComponent() {
    const {counter, setCounter} = useCounterContext()

    const handleClick = () => {
        setCounter(counter + 1);
    }

    return <>
        <h2>First Component</h2>
        <button onClick={handleClick}>Raise counter amount by context</button>
    </>
}

export default FirstComponent;
```

En el `SecondComponent` vamos a mostrar el valor del `counter` accediendo a el por medio de nuestro `useCounterContext`:

```jsx
function SecondComponent() {
    const {counter} = useCounterContext()
    return <>
        <h2>Second Component</h2>
        <p>
            Display context counter value: {counter}
        </p>
    </>
}

export default SecondComponent;
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7nujx20mtgmpm3xtqsi4.png)

> Código: [https://github.com/gon250/use-react-context-example](https://github.com/gon250/use-react-context-example)