Context API

Context API proporciona una forma de compartir datos entre componentes sin pasar props manualmente a todos los niveles.

Nuestro objeto Provider se encargará de hacer visible el objeto que le pasemos para todos los componentes anidados en él.

El provider sólo puede utilizar la prop value para determinar la información que va a ser almacenada. Por tanto, si queremos almacenar varios valores, lo que haremos será usar un objeto con múltiples propiedades.

Context API 1
./src/App.js
import Provider from './app/Provider';
import ShowState from './pages/showstate';
import LogIn from './pages/login';

const App = () => (
    <Provider>
      <LogIn />
      <ShowState />
    </Provider>
  );

export default App;
./src/app/Provider.js
import {createContext,useState} from 'react';

const Provider = ({ children }) =>{
    const [state,setState] = useState({});
    return (            
            <AppContext.Provider value={[state,setState]}>
                {children}
            </AppContext.Provider>  
    );
}

export default Provider;
export const AppContext = createContext();
./src/pages/Login.js
import {useContext} from 'react';
import {AppContext} from '../app/Provider';

const Login = () =>{
    const [state,setState] = useContext(AppContext);

    return( <input type="text" onChange={ (e) => {setState({ ...state, name:e.target.value})}} />
    );
}

export default Login;
./src/pages/Showstate.js
import { useContext } from 'react';
import { AppContext } from '../app/Provider';

const Showstate = () => {
  const [state, setState] = useContext(AppContext);
  return ( <p>{state.name}</p> );
}

export default Showstate;

Añadiendo lógica al Provider

Es posible añadir métodos específicos para gestionar el contexto.

const CartContext = ({ children }) => {
    const [items, setItems] = useState([]);
    const addItem = (newItem, quantity) => {
        !items.find(item => item.id === newItem.id) && setItems([...items, { ...newItem, quantity }]);
    };
    const removeItem = id => setItems(items.filter(item => item.id !== id));
    const clear = () => setItems([]);
    const isInCart = (id) => items.find(item => item.id === id) ? true : false;

    return (
        <AppContext.Provider value={{items, addItem, removeItem, clear, isInCart}}>
            {children}
        </AppContext.Provider>
    );
}

Para acceder a estos datos, utilizaré la deconstrucción de un objeto:

const { items, addItem, removeItem, clear } = useContext(AppContext);
← Problema usando useState y setTimeout
Redux en React →