React Context fornisce un metodo alternativo per gestire lo stato dell'applicazione.

Normalmente lo stato di una applicazione viene mantenuto nel componente di root e fatto passare, tramite le proprietà, agli altri componenti con la tecnica detta Prop Drilling.
React Prop Drilling
React Prop Drilling
con React Context API è possibile spostare lo stato al di fuori dell'applicazione ed accedervi direttamente da ogni singolo componente
React Context
React Context
Questo approccio risulta molto utile nel caso di componenti molto annidati.

Context

Per usare React Context sono necessari 3 passi
  • Definire un contesto
  • Definire un provider
  • Consumare il contesto

Definire un contesto

Il contesto va definito con l'istruzione React.createContext

React JSX: UserContext

import * as React from 'react';

// come esempio gestisco lo stato dell'utente
export interface IUser {
  loginName: string;
  modified: Date;
}

// il contesto comprenderà la proprietà ed il metodo per modificare IUser
interface IUserContext {
  user: IUser;
  setUser: (loginName: IUser) => void
}

// creo il contesto
const UserContext = React.createContext<IUserContext | null>(null);

export default UserContext;

Definire un provider

Successivamente va completato con la definizione di un provider

React JSX: UserProvider

import * as React from 'react';
import { FC, ReactElement, useState } from 'react';

export interface IUser {
  loginName: string;
  modified: Date;
}

interface IUserContext {
  user: IUser;
  setUser: (loginName: IUser) => void
}

// definisco il tipo di proprietà che verranno passate al Provider
type UserProviderProps = {
  user: IUser, // valore di default del contesto
  children: JSX.Element  // gli elementi figli del provider
};

const UserContext = React.createContext<IUserContext | null>(null);

// creo una funzione (FC) che rappresenta il Provider
export const UserProvider: FC<UserProviderProps> = (props): ReactElement => {

  // uso useState per memorizzare lo stato del contesto
  const [user, setUser] = useState<IUser>({
    loginName: props.user.loginName,
    modified: new Date
  });

  return (
    // definisco il Provider del context passando lo stato da memorizzare
    <UserContext.Provider value={{ user, setUser }}>{props.children}</UserContext.Provider>
  )
}

export default UserContext;

Consumare il contesto

Per poter consumare il contesto, prima di tutto, devo fare il wrap del componente di root con il provider UserProvider

React JSX: Root UserProvider

import * as React from 'react';
import styles from './HelloWordContext.module.scss';
import { IHelloWordContextProps } from './IHelloWordContextProps';
import { UserProvider } from '../contexts/UserContext';

export default class HelloWordContext extends React.Component<IHelloWordContextProps, {}> {
  public render(): React.ReactElement<IHelloWordContextProps> {

    return (
      <UserProvider user={{loginName: 'utente1', modified: new Date()}}>
        <sectio className={`${styles.helloWordContext} ${hasTeamsContext ? styles.teams : ''}`}>
            <ShowUser />
            <hr />
            <ButtonUser />
        </section>
      </UserProvider>
    );
  }
}
L'esempio è basato su un progetto SPFx.

A questo punto posso creare un componente ShowUser che consuma i dati del contesto

React JSX: ShowUser

import * as React from 'react';
import { FC, ReactElement } from 'react';
import UserContext from '../contexts/UserContext';

const ShowUser: FC = (): ReactElement => {

  // recupero il contesto
  const { user } = React.useContext(UserContext);

  const modified = new Intl.DateTimeFormat('it-IT', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  }).format(user?.modified)

  return (
      <span>LoginName: {user?.loginName}, modified: {modified}</span>
  )
};

export default ShowUser;
Notare l'uso di Intl.DateTimeFormat(...) per formattare le date in italiano senza l'uso di librerie esterne.
Oltre a visualizzare i dati del contesto, posso anche modificarlo

React JSX: ButtonUser

import * as React from 'react';
import { FC, ReactElement } from 'react';
import UserContext from '../contexts/UserContext';

const ButtonUser: FC = (): ReactElement => {

  // recupero il contesto e quello che mi serve
  const { user, setUser } = React.useContext(UserContext);

  // creo un handler che al click modifica la data modified
  const handlerClick = (): void => setUser({ loginName: user.loginName, modified: new Date() });

  return (
    <button type='button' onClick={handlerClick}>Set date</button>
  )
};

export default ButtonUser;

Vedi anche React Context.
Tags:
React17 SPFx18 SharePoint Online77
Potrebbe interessarti anche: