web-dev-qa-db-fra.com

Erreur de réaction des crochets: les crochets ne peuvent être appelés que dans le corps d'un composant de fonction

Je reçois cette erreur lorsque j'utilise le hook useState. J'ai ceci dans sa forme de base, en regardant les react docs pour une référence, mais j'ai toujours cette erreur Je suis prêt pour le visage moment Palm ...

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

Mise à jour: 2018-déc.

La nouvelle version de react-hot-loader est disponible, link . Hooks fonctionne maintenant hors de la boîte. Merci à l'auteur, theKashey.

Découvrez cette plate-forme https://github.com/ReeganExE/react-hooks-boilerplate

  • Crochets à réaction
  • 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.

Ensuite, vérifiez si vous utilisez react-hot-loader ou non.

Dans mon cas, désactivez Hot Load et HMR pourrait le faire fonctionner.

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

Cité

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

Les SFC sont convertis en composants de classe. Il y a une raison - être capable de forcer la mise à jour sur HMR, tant qu'il n'y a pas de méthode "update" sur SFC. Je cherche un autre moyen de forcer la mise à jour (comme ceci. Donc RHL tue SFC.

"hotReplacementRender". RHL essaie de faire le travail de React et de rendre l'ancienne et la nouvelle application, pour les fusionner. Donc, évidemment, c'est cassé à présent.

Je vais rédiger un PR pour atténuer ces deux problèmes. Cela fonctionnera, mais pas aujourd'hui.

Il existe un correctif plus approprié, qui fonctionnerait - API froide

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

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

cold(MyComponent);

Recherchez "useState/useEffect" dans le code source du composant et faites-le "froid".

Mis à jour:

Selon updated de mainten-react-hot-loader, vous pouvez essayer react-hot-loader@next et définir la configuration comme suit:

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.

31
Ninh Pham

Mon problème était d'oublier de mettre à jour le module react-dom. Voir le numéro .

18
JLarky

Le problème pour moi était en effet react-hot-loader .

Vous pouvez désactiver react-hot-loader pour un seul composant au lieu de l'application entière à l'aide de la méthode cold comme ceci:

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

export const YourComponent = cold(() => {

  // ... hook code

  return (
    // ...
  )
})

OR

export default cold(YourComponent)
2
protoEvangelion

J'ai rencontré cette erreur en utilisant Remplacement du module actif de Parcel , et je l'ai corrigé en mettant à jour react-dom vers sa version alpha:

yarn add [email protected]

Voir ce numéro.

2
erica mitchell

trouvé cette solution de contournement pour react-hot-loader alors que le PR concerné pour le corriger est entrant.

Enveloppez la fonction qui appelle les points d'ancrage dans un React.memo, empêchant un rechargement à chaud s'il n'est pas modifié.

const MyFunc = React.memo(({props}) => {...

Crédit pour solution: https://github.com/gatsbyjs/gatsby/issues/9489

1
Chance Eakin

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

J'importe useState dans mon fichier de composant:

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 crochet:

// 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 me moquer de la bibliothèque de React pour fournir les hooks primitifs. Au lieu de cela, nous pouvons passer un hook simulé useState directement dans la fonction du hook personnalisé. Je pense que cela améliore la qualité du code, car vos hooks personnalisés ne sont plus couplés avec la bibliothèque React, ce qui permet une programmation et des tests fonctionnels plus naturels.

1
mickmister

Si vous utilisez l'application Create React, vous devez également mettre à jour la version "react-scripts" avec les versions de réagir et réagir.

 "react-scripts": "2.1.5",
 "react": "^16.8.1",
 "react-dom": "^16.8.1",

cette combinaison fonctionne bien.

0
Kartik_Agarwal

J'ai eu un problème dans un monorepo, où un paquet docz used [email protected] et le paquet de sortie final avaient deux versions de réaction.

Numéro sur Github

Fixé en supprimant le paquet ????

0
rista404

Mon problème était le suivant:

Je faisais: ReactDOM.render(Example(), app);

Alors que j'aurais dû faire: ReactDOM.render(<Example />, app);

0
nwparker

Avait 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} />
0
peternyc