DEV Community

Cover image for React - Context API
gugadev
gugadev

Posted on

React - Context API

Hasta antes de la versión 16, solo había una forma -nativa- de compartir propiedades entre componentes y era por medio de Prop drilling o, dicho en español, taladramiento ,que quiere decir, que las propiedades fluyen de arriba hacia abajo en una jerarquía previamente establecida.

Prop Drilling y Redux

Era común tener componentes como el siguiente:

class Me extends React.Component<P, S> {
  state = {
    lastName = 'Garzaki'
  }
  render = _ => (
    <div>
      <p>Hola, yo soy Gustavo {this.state.lastName} y mi niña se llama </p>
      <Child lastName={this.state.lastName} />
    </div>
  )
}

class Child extends React.Component<P, S> {
  render = _ => (
    <p>Mía {this.props.lastName}</p>
  )
}
Enter fullscreen mode Exit fullscreen mode

A esto se le llama prop drilling que no es más que pasar las propiedades de padre a hijo, de hijo a nieto, de nieto a bisnieto y así sucesivamente. Con el pasar del tiempo llegaron nuevas librerías complementarias para React, como Redux, Mobx, entre otras, que lo que ofrecen es un manejo de estados intercomponentes, el cual es global, de manera que no es necesario taladrar toda la jerarquía de componentes para pasar propiedades desde el componente A hasta el F dentro de la jerarquía, si no que solo necesitas subscribirte al estado o a una parte de él para estar escuchando por cambios en las propiedades que forman parte de esa porción del estado. Además de esto, nos proveen una manera realmente sencilla de compartir propiedades entre hermanos.

68747470733a2f2f766963746f72766870672e6769746875622e696f2f6173736574732f636f6e746575646f2d706f7374732f323031382f72656475782f72656475782e706e67

Sin embargo, esto trajo consigo una consecuencia inminente e inevitable: complejidad. Necesitábamos tener en cuenta los middlewares, las acciones, configurar el store, entre otros, lo que hacía y hace aún a Redux bastante complejo de implementar.

Context API - ¿Alternativa a Redux? 🤔

A partir de React 16, se implementó una nueva herramienta conocida como Context API. Esta nueva herramienta se creó como propuesta al prop drilling y a Redux. La idea detrás de Context API es la misma que Redux, pero de manera mucho más ligera, concisa y lo mejor de todo, oficial.

Esta nueva característica funciona creando un contexto, que es un entorno en tiempo de ejecución que guarda ciertos datos, como variables, funciones, entre otras. Este contexto se divide en dos: Provider y Consumer.

prop-drilling-v-context.png

Para crear un contexto, basta con usar el método React.createContext:

const AppContext = React.createContext({})
export const AppProvider = AppContext.Provider
export const AppConsumer = AppContext.Consumer
Enter fullscreen mode Exit fullscreen mode

El Provider es donde se almacena la información que se quiere consumir; esta información se pasa por un atributo llamado value. Piensa en esto como si fuese una API a la cual vamos a consumir.

Por otro lado, el Consumer es el elemento que se encarga de consumir los datos que contiene el Provider, de manera que actúa como un proxy para nuestros componentes.

import { AppProvider, AppConsumer } from './context'

class App extends Component<P, S> {
  state = {
    title: 'Hello from App',
    updateTitle: title => {
      this.setState({ title })
    }
  }
  render = _ => (
    <AppProvider value={this.state}>
      <Header />
      {this.props.children}
    </AppProvider>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Una vez que el Provider ya tiene un valor, se puede consumir sin importar la profundidad en donde se encuentre el componente que desea consumir la información:

const Header = _ => (
  <header className="header">
    <Title />
  </header>
)
Enter fullscreen mode Exit fullscreen mode
const Title = _ => (
  <AppConsumer>
  {
    context => (
      <h1 className="header__title">
        { context.title }
      </h1>
    )
  }
)
Enter fullscreen mode Exit fullscreen mode

Como vemos, a pesar que el componente Title no es hijo directo de App, podemos hacer uso de su estado sin heredarlo como propiedad, aún si Title estuviese a muchos niveles más de profundidad.

No solo eso, también podemos actualizar el valor del Provider actualizando el estado del componente que lo provee. Las posibilidades son muchas y depende de ti como desarrollador decidir el uso que le quieres dar.


Conclusiones

Context API es una alternativa bastante buena a Redux. Si lo que buscas es algo simple y funcional, es la opción para ti. Sin embargo, pueden existir ocasiones en que no sea lo suficientemente útil para ti y quieras usar Redux y otra alternativa. En lo personal, me basta con Context API e incluso para crear mi propio Redux basada en ella como React Waterfall.

Top comments (5)

Collapse
 
antonio_pangall profile image
Antonio Pangallo

Hi Gustavo,

my Spanish is not good :) sorry for that.

I would like to get your opinion on github.com/iusehooks/redhooks which uses the Context API and the Hooks.

Thanks!

Collapse
 
gugadev profile image
gugadev

Hi Antonio, redhooks looks pretty good. It's very similar to Redux in fact. I'll try it and make some tutorial about it ;)

Thanks for the link!

Collapse
 
antonio_pangall profile image
Antonio Pangallo

it depends only on react hooks and context api. You do not need react-redux to use it, middleware are supported and it is really a tiny library. Thanks for your feedback

Collapse
 
dontacho profile image
dontacho

Hola Gus, muy buena explicación. Justo estoy presentando complejidad con props y esto parece la solución. Saludos y gracias.

Collapse
 
gugadev profile image
gugadev

Hi there! Gracias! Esto lo puedes aprovechar mejor con el hook useContext! Ya cocinaré algo al respecto. 🤙