85 votes

React Hooks Erreur : Les crochets ne peuvent être appelés qu'à l'intérieur du corps d'un composant de fonction.

J'obtiens cette erreur lorsque j'utilise le useState crochet. Je l'ai dans sa forme de base, en regardant le docs sur les réacteurs pour une référence, mais je reçois toujours cette erreur. Je suis prêt pour le moment de la paume de la main...

export function Header() {
  const [count, setCount] = useState(0)
  return <span>header</span>
}

2 votes

Cela fonctionne pour moi... aucune erreur... avez-vous mis à jour vers la 16.7 ?

0 votes

Oui, je l'ai fait. Je pense que ça a peut-être quelque chose à voir avec ma configuration, mais je ne sais pas quoi. Eventuellement, si j'utilise ce même crochet en haut du composant function App, j'obtiens la même erreur.

0 votes

Hmmm... tout ce que j'ai fait c'est npx create-react-app newhook et ensuite yarn add react@next et react-dom@next et ça a bien marché....

42voto

Reegan Points 131

Mis à jour : 2018-Dec

Nouvelle version de react-hot-loader est sorti maintenant, lien . Hooks travaille maintenant hors de la boîte. Merci à l'auteur, theKashey.

Regardez ce modèle https://github.com/ReeganExE/react-hooks-boilerplate

  • Crochets React
  • React Hot Loader
  • Webpack, Babel, ESLint Airbnb

Réponse précédente :

Tout d'abord, assurez-vous d'avoir installé react@next et react-dom@next .

Vérifiez ensuite si vous utilisez react-hot-loader ou pas.

Dans mon cas, désactiver le chargeur à chaud et le HMR pourrait le faire fonctionner.

Voir https://github.com/gaearon/react-hot-loader/issues/1088 .

Citée :

Oui. RHL est 100% non compatible avec les crochets. Il y a juste quelques raisons derrière cela :

Les SFC sont en cours de conversion en éléments de classe. Il y a une raison - de pouvoir de pouvoir forcer la mise à jour de l'HMR, tant qu'il n'y a pas de méthode de mise à jour sur les SFC. SFC. Je cherche un autre moyen de forcer la mise à jour (comme ceci. Donc RHL tue SFC.

"hotReplacementRender". RHL essaye de faire le travail de React, et render l'ancienne et la nouvelle application, pour les fusionner. Donc, évidemment, c'est cassé maintenant.

Je vais rédiger un PR, pour atténuer les deux problèmes. Ça va marcher, mais pas aujourd'hui.

Il y a une solution plus appropriée, qui fonctionnerait API froid

Vous pouvez désactiver RHL pour tout type de personnalisation.

import { cold } from 'react-hot-loader';

cold(MyComponent);

Recherche de "useState/useEffect" à l'intérieur du code source du composant, et le "refroidir".

Mis à jour :

Conformément à actualisé du mainteneur react-hot-loader, vous pourriez essayer react-hot-loader@next et définissez la configuration comme ci-dessous :

import { setConfig } from 'react-hot-loader';

setConfig({
  // set this flag to support SFC if patch is not landed
  pureSFC: true
});

Merci à @loganfromlogan pour la mise à jour.

0 votes

Merci de me le signaler :). J'utilise react-hot-loader, il serait donc logique que cela ne fonctionne pas. Cependant, je ne suis pas encore sûr à 100% qu'il n'y a pas quelque chose d'autre qui se passe aussi. Je vais suivre ce problème sur react-hot-loader, et je mettrai à jour cette question dès qu'un correctif sera posté.

0 votes

Je peux maintenant confirmer que la désactivation de react-hot-loader a résolu cette erreur.

2 votes

En outre, si par hasard vous rendez votre composant sous forme d'appel de fonction jsx en ligne, l'erreur persistera, même si le composant est entouré de l'option cold . Donc {MyComponent(props)} ne fonctionnera pas, mais <MyComponent {...props} /> lo hará.

33voto

JLarky Points 1425

Mon problème était d'oublier de mettre à jour react-dom module. Voir la question .

3 votes

Moi aussi ! J'utilise create-react-app et Typescript.

1 votes

J'utilise react et react-dom version 16.8.3 mais j'ai toujours le même problème.

22voto

peternyc Points 217

J'ai eu le même problème. Mon problème était lié à React Router. J'avais accidentellement utilisé

<Route render={ComponentUsingHooks} />

au lieu de

<Route component={ComponentUsingHooks} />

3 votes

Ce commentaire m'a aussi sauvé la vie. J'ai perdu 3 heures avec ça et j'ai mis mon projet en pièces. Il y avait une faute de frappe dans le routeur

1 votes

Je rendais le composant en tant qu'enfant dans l'élément Route en tant que <Route>{component}</Route> et la solution a fait l'affaire

0 votes

J'ai passé tout mon après-midi là-dessus. Merci !

3voto

mickmister Points 55

J'ai pu résoudre ce problème en important les hooks primitifs de React dans le fichier du composant, puis en les passant dans mes hooks personnalisés. Pour une raison quelconque, l'erreur ne se produit que lorsque j'importe le crochet React (comme useState) dans mon fichier de crochet personnalisé.

J'importe useState dans mon fichier de composants :

import React, {useState} from 'react'; // import useState

import {useCustomHook} from '../hooks/custom-hook'; // import custom hook

const initialState = {items: []};
export default function MyComponent(props) {
    const [state, actions] = useCustomHook(initialState, {useState});
    ...
}

Puis dans mon fichier de crochets :

// do not import useState here

export function useCustomHook(initialValue, {useState}) {
    const [state, setState] = useState(initialValue || {items: []});

    const actions = {
        add: (item) => setState(currentState => {
            const newItems = currentState.items.concat([item]);
            return {
                ...currentState,
                items: newItems,
            };
        }),
    };

    return [state, actions];
}

Cette méthode a amélioré la testabilité de mes hooks car je n'ai pas besoin de mocker la bibliothèque de React pour fournir les hooks primitifs. Au lieu de cela, nous pouvons passer un objet fantaisie useState directement dans la fonction du crochet personnalisé. Je pense que cela améliore la qualité du code, car vos hooks personnalisés n'ont désormais aucun couplage avec la bibliothèque React, ce qui permet une programmation fonctionnelle et des tests plus naturels.

3voto

rista404 Points 5904

J'ai eu un problème dans un monorepo, où un paquet docz utilisé react@16.6.3 et le paquet final de sortie avait deux versions de réaction.

Publication sur Github

Corrigé en supprimant le paquet

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X