
MCP Server : Implémenter un serveur Model Context Protocol en TypeScript
Découvrez comment créer un serveur MCP en TypeScript à l'aide du SDK officiel. Apprenez à fournir un contexte riche aux LLMs.
Les hooks arrivent avec la release de la version 16.8 de React (sans breaking changes !), et amènent avec eux la solution à de nombreux problèmes causés par certains patterns.
Nous allons comparer ensemble les deux méthodes les plus populaires avant l’arrivée des hooks : les HOC et les renderProps. Il est intéressant de voir quels problèmes peuvent poser ces méthodes, et comment les hooks simplifient le code et résolvent ces problèmes.
Prenons un exemple qui montre la position de la souris.
Voilà à quoi ressemble le code classique :
import React, { Component } from 'react';
export default class MouseRender extends Component {
state = { x: 0, y: 0 };
componentDidMount() {
window.addEventListener('mousemove', this.onMouseMove);
}
componentWillUnmount() {
window.removeEventListener('mousemove', this.onMouseMove);
}
onMouseMove = e => this.setState({ x: e.clientX, y: e.clientY });
render() {
const { x, y } = this.state;
return (
<span>
Mouse X : { x }, Mouse Y: { y }
</span>
);
}
};
Ce code peut vite poser problème, principalement pour deux raisons :
componentDidMount
et du componentWillUnmount
.Voilà comment on peut régler le problème avec les deux méthodes dont nous avons parlé plus haut :
Un HOC est une fonction qui prend un composant en paramètre, et retourne un nouveau composant en lui ajoutant un comportement (voir le decorator pattern). Cela permet de séparer la logique et le rendu dans le DOM. Voilà donc à quoi ressemble le même code en utilisant un HOC :
import React, { Component } from 'react';
const withMousePosition = ComponentToWrap => {
return class MousePositionHoc extends Component {
state = { x: 0, y: 0 };
componentDidMount() {
window.addEventListener('mousemove', this.onMouseMove);
}
componentWillUnmount() {
window.removeEventListener('mousemove', this.onMouseMove);
}
onMouseMove = e => this.setState({ x: e.clientX, y: e.clientY });
render() {
return (
<ComponentToWrap { ...this.state } />
);
}
}
};
class MouseRender extends Component {
render() {
const { x, y } = this.props;
return (
<span>
Mouse X : { x }, Mouse Y: { y }
</span>
)
}
}
const EnhanceMouseRender = withMousePosition(MouseRender);
export default EnhanceMouseRender;
Les HOC posent plusieurs problèmes :
Une autre solution est d’utiliser les renderProps, qui permettent de partager la logique entre plusieurs composants en passant en propriété d’un composant une fonction qui permet de générer un autre composant :
import React, { Component } from 'react';
class MousePosition extends Component {
state = { x: 0, y: 0 };
componentDidMount() {
window.addEventListener('mousemove', this.onMouseMove);
}
componentWillUnmount() {
window.removeEventListener('mousemove', this.onMouseMove);
}
onMouseMove = e => this.setState({ x: e.clientX, y: e.clientY });
render() {
return (
this.props.children(this.state)
);
}
};
export default class MouseRender extends Component {
render() {
return (
<MousePosition>
{({ x, y }) => (
<span>Mouse X : { x }, Mouse Y: { y }</span>
)}
</MousePosition>
)
}
}
Le principal intérêt d'utiliser des renderProps, c'est d'éviter la duplication de code. Cependant les renderProps amènent certains problèmes :
PureComponent
devient compliqué : le shallow comparison retournera toujours faux pour les nouvelles props, et chaque render générera donc une nouvelle valeur pour la prop (voir la doc).La nouvelle fonctionnalité, les hooks, pourrait donc être une alternative qui éliminerait les soucis rencontrés par ces différentes méthodes.
Les hooks sont des fonctions qui permettent d’aller chercher les données dans le state et dans le lifecycle à partir de fonctions. Il ne faut les utiliser qu’au plus haut niveau, et il ne faut donc pas les appeler dans des boucles, des conditions, des classes ou des nested functions. Les hooks sont toujours appelés dans le même ordre.
Pour reprendre l’exemple de la souris, voici à quoi ressemble le code avec l’utilisation des hooks :
import React, { useState, useEffect } from 'react';
const useMousePosition = () => {
const [position, setMousePosition] = useState({ x: 0, y: 0 });
const handleMouseMove = e => setMousePosition({ x: e.clientX, y: e.clientY });
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
});
return position;
}
const MouseRender = () => {
const mouse = useMousePosition();
return (
<span>Mouse X : { mouse.x }, Mouse Y: { mouse.y }</span>
)
}
export default MouseRender;
Comme on peut le voir, on utilise 2 hooks dans ce code :
useState
, comme son nom l’indique, permet d’utiliser le state : le premier argument étant le state initial (qui n’a pas nécessairement besoin d’être un objet), et le second étant la fonction à appliquer sur cette valeur.useEffect
indique que le composant peut causer des effets de bord comme par exemple fetcher des données ou modifier manuellement le DOM et vient remplacer componentDidMount
, componentDidUpdate
et componentWillUnmount
dans la même API.Il est aussi possible de créer ses propres hooks : il suffit de créer une fonction Javascript qui commence par « use » et qui appelle d’autres hooks. Dans notre exemple, il s’agit de la fonction useMousePosition
.
Il existe d’autres hooks, comme useContext
qui utilise le context API, ou useReducer
qui permet de manager son state local avec des reducers, à la manière de redux.
Les hooks ne sont pas indispensables à votre code, mais vous permettront de créer des composants qui n'ont plus besoin de classes, et vous permettront de gagner de nombreuses lignes de code. Il existe de nombreux hooks qui vous faciliteront la vie. La hype autour des hooks est justifiée par les changements qu'ils vont probablement apporter à l'écosystème React.
Il y a beaucoup à dire sur les hooks, cet article est loin d’être exhaustif ! Pour les anglophones, n’hésitez pas à cliquer sur ce lien qui vous donnera toutes les ressources nécessaires !
Auteur(s)
Mehdi Druon
Jeune développeur JS, j'aime me tenir au courant, et j'aime le piment d'espelette.
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Découvrez comment créer un serveur MCP en TypeScript à l'aide du SDK officiel. Apprenez à fournir un contexte riche aux LLMs.
Découvrez comment créer un plugin ESLint en TypeScript avec la nouvelle configuration "flat config" et publiez-le sur npm.
Apprenez à concevoir une barre de recherche accessible pour le web, conforme RGAA. Bonnes pratiques, erreurs fréquentes à éviter et exemples concrets en HTML et React/MUI.