IFT3225

Une requête-réponse n’est pas qu’un échange technique : elle commence et finit chez une personne. L’interface est le point où l’intention humaine devient protocole, et où la réponse du serveur redevient quelque chose de compréhensible. Cette page part de ce rôle, rappelle ce qui rend une interface utilisable, introduit la réactivité, puis montre comment la construire par blocs dans le navigateur.

1. Le rôle de l’interface dans la communication

Tout part d’une intention : l’utilisateur veut quelque chose. L’interface traduit cette intention en une interaction (un geste, une saisie), qui devient une requête. Le serveur la traite et renvoie une réponse, que l’interface transforme en un changement d’affichage. L’utilisateur évalue ce changement, ce qui reforme une intention. La boucle recommence.

Utilisateurformuleune intentionévaluele résultatInterface(navigateur)traduit l’intentionen requêtetraduit la réponseen affichageServeurtraitela requêteintentionrequêteréponseaffichagenouvelle intention
L’interface est le maillon qui traduit l’intention en requête, puis la réponse en affichage. La boucle se referme par l’évaluation.
L’interface ne montre pas le protocole : elle le rend agissable, en amont, et lisible, en aval. Concevoir une interface, c’est concevoir cette double traduction.

2. Heuristiques et bonnes pratiques d’utilisabilité

Avant de parler de réactivité, voyons ce qui rend généralement une interface utilisable. Les heuristiques de Nielsen en donnent une liste éprouvée. Les plus utiles ici :

À ces heuristiques s’ajoutent les principes de Norman : les affordances (ce qu’un objet permet de faire), les signifiants (les indices qui le donnent à voir), le retour d’information, la correspondance entre commandes et effets, les contraintes qui guident, et un modèle conceptuel clair que l’utilisateur peut se forger.

3. Réactivité, transparence et contrôle

Une interface réactive reflète en continu l’état du système et les actions possibles, et garde l’utilisateur aux commandes. Trois exigences la résument.

  1. Rendre visible l’état (retour d’information) : chargement, succès, erreur, hors ligne. Une action sans retour laisse l’utilisateur dans le doute.
  2. Rendre lisibles les actions possibles et permises (affordances, signifiants, contraintes) : on voit ce qu’on peut faire, et ce qui est interdit ou désactivé, sans deviner.
  3. Garder l’utilisateur en contrôle : pouvoir annuler, comprendre ce qui se passe, ne pas être surpris par un changement qu’on n’a pas déclenché.

Quand une de ces exigences manque, l’interface trahit l’utilisateur, qu’elle soit physique ou numérique.

Le piège le plus subtil : une interface séduisante mais opaque. Un design très épuré où rien ne signale qu’un élément est cliquable, une animation qui masque ce qui charge vraiment. Une belle interface opaque trahit l’utilisateur autant qu’une laide.
VérificationUn bouton « Envoyer » lance une requête, mais l'interface ne change pas pendant l'attente. Quelle exigence est violée, et que se passe-t-il côté utilisateur ?

La visibilité de l’état : sans retour, l’utilisateur ne sait pas si son action a été prise en compte. Il risque de recliquer (et d’envoyer deux fois), ou d’abandonner en pensant à un bug. Un simple indicateur de chargement, ou un bouton désactivé pendant l’attente, rétablit la transparence et le contrôle.

Refléter l’état n’est pas un instantané pris au chargement : une interface réactive s’adapte à l’état et le suit dans le temps.

Adapter l’interface à l’état. La forme même de l’interface dépend de l’état.

Mettre à jour en continu (temps réel). L’état ne change pas qu’à l’initiative de l’utilisateur : le temps passe, le serveur pousse une donnée, un autre usager agit. L’interface doit continuer de refléter l’état sans qu’on la rafraîchisse à la main.

Une interface réactive n’est jamais terminée une fois affichée : elle reste un miroir vivant de l’état, qu’il change par l’utilisateur, par le temps ou par le serveur.

4. Sur le web : réactivité et composition par blocs

Le navigateur nous expose des outils, le DOM, les événements et la liaison de données, avec lesquels nous construisons des interfaces réactives sous forme de pages web. On structure alors l’interface en blocs (des composants), chacun avec un rôle, un sous-état, des entrées et des sorties. Les blocs communiquent par l’état partagé et par des événements, jamais en lisant le contenu des autres.

5. Méthodologie : construire une interface par étapes

On ne dessine pas une interface d’un seul trait. On procède par blocs et par état. Prenons un panneau de signalement d’arrivée d’autobus pour un arrêt : choisir un arrêt, signaler une arrivée, et rechercher les signalements d’une ligne.

Étape 1 : identifier les blocs, leurs rôles et le sous-état

Bloc Rôle Rapport à l’état
Sélecteur d’arrêt choisir l’arrêt courant écrit arretSelectionne
Signalements récents afficher les signalements de l’arrêt lit (filtré par l’arrêt)
Formulaire de signalement saisir une ligne et un délai, signaler écrit signalements
Bandeau d’état montrer l’arrêt et le nombre de signalements actifs lit (donnée dérivée)
Recherche par ligne filtrer les signalements par numéro de ligne lit (filtré par la ligne)

L’état partagé se réduit à deux pièces centrales : arretSelectionne et signalements. La ligne cherchée est une petite donnée propre au bloc de recherche. Le reste (la liste filtrée, le nombre d’actifs) s’en dérive, sans être stocké à part.

Étape 2 : identifier les mécanismes d’interaction et la paramétrisation

Chaque bloc se décrit par ses entrées (ce qu’on lui passe) et ses sorties (ce qu’il émet).

Bloc Entrées Sorties
Sélecteur liste des arrêts, arrêt courant onChoisir(arretId)
Signalements récents signalements de l’arrêt onRetirer(id)
Formulaire lignes de l’arrêt onSignaler({ ligne, delai })
Recherche par ligne liste des signalements onRechercher(ligne)
Bandeau arrêt, nombre d’actifs (aucune)
Le motif est toujours le même : les données descendent (en paramètres), les événements remontent (en rappels). Un bloc ne modifie jamais un autre bloc directement ; il signale au parent, qui met à jour l’état.

Étape 3 : composer jusqu’à l’interface complète

Un composant parent détient l’état partagé, distribue les données filtrées et reçoit les événements pour mettre à jour l’état. Toutes les vues se redessinent.

function Panneau() {
  const [arret, setArret] = useState("a1");
  const [signalements, setSignalements] = useState([]);

  const visibles = signalements.filter((s) => s.arretId === arret);

  return (
    <>
      <SelecteurArret valeur={arret} onChoisir={setArret} />
      <SignalementsRecents items={visibles} />
      <FormulaireSignalement
        arret={arret}
        onSignaler={(sig) => setSignalements((prev) => [sig, ...prev])}
      />
    </>
  );
}

Illustration du panneau composé

Bus en vue

L'arrivée des autobus, entre usagers

Arrêt
Ligne
Arrive dans
Récents à cet arrêt
  • 11arrive dans ~3 minil y a 22 s
  • 361arrive dans ~7 minil y a 1 min

6. À retenir

Idée Point clé
Rôle de l’interface Traduire l’intention en requête, puis la réponse en affichage ; la boucle se referme par l’évaluation
Utilisabilité Heuristiques de Nielsen et principes de Norman : rendre visibles l’état et les actions
Réactivité Montrer l’état, montrer les actions possibles et permises, garder l’utilisateur en contrôle
Échecs courants Action sans retour, état caché, affordance absente ; une belle interface peut être opaque
Composition par blocs Des composants avec un sous-état, reliés par un état partagé ; données vers le bas, événements vers le haut