
Série SPFx : Extensions
Plongée dans les blocs de construction essentiels des extensions SPFx
Lorsque vous commencez à créer des composants SharePoint Framework, l’une des premières choses qui peut vous embrouiller est de comprendre la différence entre les props et l’état. Je vois des développeurs les confondre tout le temps, alors clarifions cela une bonne fois pour toutes.
La principale différence entre les props et l’état est simple : les props sont des valeurs de configuration qui proviennent de l’extérieur de votre composant, tandis que l’état est une donnée interne que votre composant gère lui-même. Pensez aux props comme aux paramètres que quelqu’un vous donne, et à l’état comme aux notes que vous gardez pour vous-même.
Les props (abréviation de propriétés) définissent comment votre composant doit se comporter ou apparaître. Ce sont les boutons et interrupteurs que les utilisateurs ou les développeurs peuvent ajuster pour personnaliser votre WebPart ou extension. Lorsque quelqu’un ajoute votre WebPart à une page et ouvre le panneau de propriétés, il modifie des props.
Regardons un exemple typique :
export interface IHelloWorldWebPartProps {
title: string;
showTitle: boolean;
description: string;
maxItems: number;
}
Dans cet exemple, nous avons défini quatre props :
Ces props sont définies dans le manifeste de votre WebPart et génèrent automatiquement des champs dans le panneau de propriétés. Lorsqu’un utilisateur change le titre de « Hello World » à « Bienvenue », il modifie une prop. Votre composant reçoit cette nouvelle valeur et se re-rend en conséquence.
Voici quelque chose d’important : votre composant ne doit jamais modifier ses propres props directement. Les props circulent dans une seule direction — du parent à l’enfant, de la configuration au composant. Si vous essayez de changer une valeur de prop à l’intérieur de votre composant, vous faites quelque chose d’incorrect.
// NE FAITES PAS CECI
public render(): void {
this.properties.title = "New Title"; // Incorrect !
// Votre code de rendu...
}
Le panneau de propriétés gère les mises à jour de props pour vous. Lorsque quelqu’un change une valeur dans le panneau de propriétés, SPFx appelle automatiquement la méthode render de votre composant avec les nouvelles valeurs de props.
C’est là que ça devient pratique. Vous définissez votre interface de props, mais comment créer réellement ces champs dans le panneau de propriétés ? Cela se produit dans la méthode getPropertyPaneConfiguration() de votre WebPart. Voir également l’autre article de blog SPFx Series: Web part properties.
Construisons sur notre exemple précédent, l’IHelloWorldWebPartProps présenté ci-dessus. Nous devons maintenant créer les contrôles réels du panneau de propriétés pour ces props :
import {
PropertyPaneTextField,
PropertyPaneToggle,
PropertyPaneSlider
} from '@microsoft/sp-property-pane';
export default class HelloWorldWebPart extends BaseClientSideWebPart {
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: "Configure your web part settings"
},
groups: [
{
groupName: "Display Settings",
groupFields: [
PropertyPaneTextField('title', {
label: 'Title',
description: 'The main heading for your web part'
}),
PropertyPaneToggle('showTitle', {
label: 'Show title',
onText: 'Visible',
offText: 'Hidden'
}),
PropertyPaneTextField('description', {
label: 'Description',
multiline: true,
rows: 3
}),
PropertyPaneSlider('maxItems', {
label: 'Maximum items to show',
min: 1,
max: 50,
step: 1,
showValue: true
})
]
}
]
}
]
};
}
}
Remarquez comment le premier paramètre de chaque contrôle du panneau de propriétés correspond au nom de la propriété dans votre interface ? C’est la connexion. Lorsque vous écrivez PropertyPaneTextField('title', {…}), vous dites à SPFx « ce champ de texte contrôle la prop title ».
La magie se produit automatiquement. Lorsque quelqu’un tape « Mon fil d’actualités » dans ce champ de texte, SPFx met à jour this.properties.title et appelle votre méthode render. Vous n’écrivez aucun code pour gérer cela — cela fonctionne tout seul.
Vous vous demandez peut-être d’où viennent les valeurs par défaut. Vous les définissez dans le manifeste de votre WebPart (HelloWorldWebPart.manifest.json) :
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "abc123...",
"alias": "HelloWorldWebPart",
"componentType": "WebPart",
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70",
"group": { "default": "Other" },
"title": { "default": "Hello World" },
"description": { "default": "Shows a hello world message" },
"officeFabricIconFontName": "Page",
"properties": {
"title": "My News Feed",
"showTitle": true,
"description": "Latest news from our organization",
"maxItems": 10
}
}]
}
Les valeurs dans la section properties sont vos valeurs par défaut. Lorsque quelqu’un ajoute votre WebPart à une page pour la première fois, ce sont les valeurs qu’il verra.
L’état est complètement différent. L’état représente des données qui changent au fil du temps et sont gérées en interne par votre composant. C’est l’information que votre composant doit suivre pendant son exécution.
Voici une interface d’état simple :
export interface IHelloWorldWebPartState {
selectedOption: string;
isLoading: boolean;
items: any[];
errorMessage: string;
}
Remarquez comme ces valeurs sont différentes des props :
Ce ne sont pas des valeurs de configuration provenant du panneau de propriétés. Ce sont des valeurs dynamiques qui changent en fonction de ce qui se passe dans votre composant en ce moment.
Dans les composants SPFx basés sur React (ce que vous construirez la plupart du temps), vous gérez l’état à l’aide de la gestion d’état de React. Voici comment vous le configurez généralement dans votre composant React :
export default class HelloWorld extends React.Component {
constructor(props: IHelloWorldProps) {
super(props);
// Initialisez votre état ici
this.state = {
selectedOption: '',
isLoading: false,
items: [],
errorMessage: ''
};
}
public componentDidMount(): void {
// Charger les données lorsque le composant est monté
this.loadItems();
}
private async loadItems(): Promise {
// Définir l'état de chargement
this.setState({ isLoading: true, errorMessage: '' });
try {
const items = await this.fetchItems();
this.setState({ items: items, isLoading: false });
} catch (error) {
this.setState({
errorMessage: 'Failed to load items',
isLoading: false
});
}
}
private handleDropdownChange = (option: string): void => {
// Mettre à jour l'état lorsque l'utilisateur fait une sélection
this.setState({ selectedOption: option });
}
public render(): React.ReactElement {
// Utiliser les props et l'état dans le rendu
const { title, showTitle } = this.props;
const { selectedOption, isLoading, items, errorMessage } = this.state;
return (
{showTitle && ## {title}}
{isLoading && }
{errorMessage && {errorMessage}}
{!isLoading && items.map(item => (
{item.title}
))}
);
}
}
Notez que l’état est utilisé dans votre fichier de composant, pas dans votre fichier de WebPart !
Chaque fois que vous appelez this.setState(), React re-rend automatiquement votre composant. C’est puissant mais aussi quelque chose dont vous devez être prudent. Si vous mettez à jour l’état trop fréquemment ou inutilement, vous pouvez causer des problèmes de performances.