Les React Hooks ont révolutionné la façon dont nous écrivons des composants fonctionnels dans React, en fournissant un moyen concis et puissant de gérer l’état et les effets secondaires.

Cependant, comme toute nouvelle fonctionnalité, elle s’accompagne de son propre ensemble de règles et de directives. Une erreur courante que les développeurs React peuvent rencontrer est l’erreur « react hooks must be called in a react function component or a custom react hook function ».

Dans cet article, nous allons plonger dans les détails de cette erreur, comprendre pourquoi elle se produit et fournir les meilleures pratiques pour la corriger.

Quelles sont les causes de l’erreur « React Hooks Must Be Called In a React Function Component or a Custom React Hook Function » ?

L’utilisation des React Hooks est soumise à certaines règles. De nombreux développeurs React sautent ces règles lorsqu’ils apprennent React, ce qui conduit à des erreurs. L’une de ces erreurs est « react hooks must be called in a react function component or a custom react hook function ».

Cette erreur se produit lorsque deux choses majeures se produisent :

  • Utilisation de React Hooks dans des composants de classe
  • Appel des React Hooks dans une fonction imbriquée

Les React Hooks, tels que useState, useEffect, et useContext, sont conçus pour être appelés au niveau supérieur d’un composant fonctionnel ou d’une fonction de hook personnalisée. Ils ne doivent également être appelés que dans des composants fonctionnels et non dans des composants de classe. Il s’agit là de deux règles majeures de React Hooks, qui garantissent que les hooks sont utilisés correctement et de manière cohérente dans les composants React.

Lorsque les hooks sont appelés à des endroits non valides, vous obtenez cette erreur : « react hooks must be called in a react function component or a custom react hook function ». Cette erreur ESLint existe en tant que sauvegarde pour empêcher les hooks d’être utilisés d’une manière qui peut causer un comportement inattendu et des bogues dans votre application React.

2 façons de corriger l’erreur « React Hooks Must Be Called In a React Function Component or a Custom React Hook Function »

Cette erreur peut être corrigée de plusieurs façons en fonction de la situation ou de la façon dont vous avez mal utilisé le React Hook.

1. N’appelez jamais les hooks React dans des composants de classe

Les hooks sont conçus pour fonctionner avec des composants fonctionnels ou des hooks personnalisés uniquement – parce qu’ils utilisent la pile d’appels des composants fonctionnels pour gérer l’état et le cycle de vie du composant. Les composants de classe n’ont pas cette pile d’appels, vous ne pouvez donc pas utiliser les hooks directement dans ces composants.

import React, { useState } from 'react';
class Counter extends React.Component {
    state = { count: 0 };
    render() {
        const [count, setCount] = useState(0);
        // Error: React Hooks must be called in a React function component or a custom React Hook function
        return (
            <div>
                <p>You clicked {count} times</p>
                <button onClick={() => setCount(count + 1)}>Click me</button>
            </div>
        );
    }
}
export default Counter;

Si vous le faites, vous obtiendrez cette erreur :

Erreur React
Erreur React

Cependant, il existe plusieurs façons de résoudre ce problème, en fonction de vos préférences. Vous pouvez décider d’utiliser state et setState avec les composants de classe, de convertir le composant en composant fonctionnel ou d’utiliser un composant d’ordre supérieur (High-Order Component ou HOC).

A. Convertir le composant de classe en composant fonctionnel

Les hooks ne peuvent fonctionner que si vous utilisez un composant fonctionnel. En effet, les hooks sont conçus pour fonctionner avec des composants fonctionnels.

Dans l’exemple ci-dessous, le composant de classe précédent est converti en composant fonctionnel :

import { useState } from 'react';

function MyComponent(props) {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

B. Utiliser un composant d’ordre supérieur (HOC)

Une façon d’utiliser les hooks dans un composant de classe est d’utiliser un composant d’ordre supérieur (HOC).

Un HOC est une fonction qui prend un composant et renvoie un nouveau composant avec des accessoires ou des fonctionnalités supplémentaires. Voici un exemple d’utilisation d’un HOC pour fournir des crochets à un composant de classe :

import React, { useState } from 'react';

function withHooks(WrappedComponent) {
  return function(props) {
    const [count, setCount] = useState(0);
    return (
      < WrappedComponent count={count} setCount={setCount} {...props} />
    );
  };
}

class MyComponent extends React.Component {
  render() {
    const { count, setCount } = this.props;
    return (
      < div>
        < p>Count: {count}< /p>
        < button onClick={() => setCount(count + 1)}>Increment< /button>
      < /div>
    );
  }
}

export default withHooks(MyComponent);

C. Utiliser des états dans un composant de classe

Enfin, supposons que vous ne souhaitiez pas modifier la syntaxe de votre composant. Vous pouvez décider d’utiliser state et setState au lieu de useState Hook :

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  handleIncrement = () => {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.handleIncrement}>Increment</button>
      </div>
    );
  }
}

export default MyComponent;

2. N’appelez jamais les hooks React à l’intérieur d’une fonction imbriquée

Une règle claire de React Hooks est que tous les hooks doivent être appelés au niveau supérieur d’un composant fonctionnel ou d’une fonction de hook personnalisée. Lorsque vous appelez un hook à l’intérieur d’une fonction imbriquée, vous avez enfreint cette règle.

Dans l’exemple ci-dessous, le hook useState est appelé dans la fonction handleClick:

import React, { useState } from 'react';
function MyComponent() {
    let count = 0;
    function handleClick() {
        const [count, setCount] = useState(0);
        setCount(count + 1);
    }
    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
        </div>
    );
}

export default MyComponent;

Vous obtiendrez l’erreur suivante :

Exemple d'erreur React
Exemple d’erreur React

Vous pouvez résoudre ce problème en déplaçant le hook en dehors de la fonction – au niveau supérieur de votre composant fonctionnel :

import React, { useState } from 'react';

function MyComponent() {
    const [count, setCount] = useState(0);

    function handleClick() {
        setCount(count + 1);
    }

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={handleClick}>Increment</button>
        </div>
    );
}

export default MyComponent;

Résumé

Dans cet article, vous avez appris ce qui cause l’erreur « react hooks must be called in a react function component or a custom react hook function », et comment elle peut être corrigée.

Suivez toujours les règles des hooks React lorsque vous travaillez et les utilisez dans vos projets React afin d’éviter de rencontrer des erreurs de ce type.

Vous cherchez la solution d’hébergement idéale pour vos applications React ? Essayez gratuitement l’hébergement d’applications de Kinsta !

Nous aimerions avoir votre avis ! Avez-vous déjà rencontré cette erreur ? Si oui, comment l’avez-vous résolue ? Avez-vous utilisé d’autres approches qui n’ont pas été abordées dans cet article ? Faites-nous part de vos commentaires dans la section ci-dessous !