DEV Community

Christhoval Barba
Christhoval Barba

Posted on

¿Cómo usar de forma correcta Context en react? Parte 1

Primero hay que entender para que usaremos context en nuestras aplicaciones.

  • Administración de estado
  • Componentes de acceso global.

Para la administración de estados dispones de combinaciones con useState y useReducer.
De esta forma lo usaremos para administrar nuestro estado de forma global. Primero definiendo nuestro context, lo llamaremos AuthenticationContext, pero para resumir será AuthContext.

import React, { useCallback, useMemo } from 'react';

interface IUserInfo {
    uuid: string;
    username: string;
    email: string;
    name: string;
}

export interface IAuthContext {
  userInfo?: IUserInfo;
  setUserInfo: (user: IUserInfo) => void;
  onLogin: (username: string) => Promise<IUserInfo | undefined>;
  onLogout: () => Promise<void>;
}

export const AuthContext = React.createContext<IAuthContext>({
  userInfo: undefined,
  setUserInfo: (user) => {
    throw new Error('Not yet implemented');
  },
  onLogin: (username) => {
    throw new Error('Not yet implemented');
  },
  onLogout: () => {
    throw new Error('Not yet implemented');
  },
});
Enter fullscreen mode Exit fullscreen mode

Nuestro AuthContext está compuesto por userInfo este atributo contendrá la información del usuario, setUserInfo nos permite asignar la información del usuario, onLogin nos permite ejecutar la petición para realizar el inicio de sesión en nuestra app.
Ahora es necesario definir nuestro Provider, este nos permitirá agregar la lógica necesaria para darle funcionalidad a nuestra aplicación. El nombre correcto para nuestro proveedor será AuthProvider y este hará uso del AuthContext.

interface Props {
  children: JSX.Element;
}

export const AuthProvider = ({ children }: Props): JSX.Element  => {
  const { userInfo, setUserInfo } = useState<IUserInfo | undefined>(undefined);

  // Iniciar Sesión
  const onLogin = useCallback(
    async (username) => {
      const user = await fetch(<server_user_login>);
      setUserInfo(user);
      return user;
    }, [setUserInfo]);

  // Cerrar sesión
  const onLogout = useCallback((userInfoLogout) => {
    await fetch(<server_user_logout>);
    setUserInfo(undefined);
  }, [setUserInfo]);

  const values = React.useMemo<IAuthContext>(() =>({
    userInfo,
    setUserInfo,
    onLogin,
    onLogout
  }))

  return (
    <AuthContext.Provider value={...values}>
      {children}
    </AuthContext.Provider>
  );
};

export default AuthProvider;
Enter fullscreen mode Exit fullscreen mode

Haciendo uso de un useState manejaremos nuestro estado userInfo, para nuestras funciones onLogin y onLogout son las encargadas de conectar nuestra app con el servidor usando peticiones HTTP usando fetch o axios.
Ya solo nos falta exponer los datos para poder hacer uso de ellos. Hacerlo de la siguiente manera nos permite centralizar el contexto y nos ahorramos una serie de validaciones, por ello usamos un hook.

import { useContext } from 'react';

import { AuthContext, IAuthContext } from 'context/authContext';

export function useAuth(): IAuthContext {
  const context = useContext(AuthContext);

  if (!context) {
    throw new Error('useAuth may be used inside of AuthContext');
  }

  return context;
}
Enter fullscreen mode Exit fullscreen mode

¿Y como usamos todo esto ahora?

En nuestra app debemos integrar el Provider.

import { AuthProvider } from 'context/authContext';

const App = () => {
  return (
    <AuthProvider>
      ...
    </AuthProvider>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Y para usar los datos en nuestros componentes tenemos la siguiente via

import { useAuth } from 'hooks/useAuth';
import { useClosable } from 'hooks/useClosable';
import { SimpleConfirmDialog } from 'components/SimpleConfirmDialog';

export const LogoutButton = () => {
  const { onLogout } = useAuth();
  const [open, onOpen, onClose] = useClosable();

  return (
    <>
    <Tooltip title="Cerrar Sesión">
      <IconButton
        onClick={onOpen}
        type="submit"
        color="secondary"
        edge="end"
        >
          <ExitToAppIcon />
      </IconButton>
    </Tooltip>
    <SimpleConfirmDialog
      open={open}
      onClose={onClose}
      onConfirm={onLogout}
      title="Cerrar sesión"
      />
  </>)
}
Enter fullscreen mode Exit fullscreen mode

Haciendo uso del hook useAuth traemos toda la lógica que hemos centralizado en los procesos anteriores y esto hace más sencillo la creación de componentes dependientes de nuestro proveedor.

Espero que esta primera parte de esta entrada sea de gran ayuda a la hora de crear Contextos y proveedores en sus aplicaciones escritas en react.

Oldest comments (0)