63
votes

Appel de hook non valide. Les hooks ne peuvent être appelés qu'à l'intérieur du corps d'un composant de fonction

Je suis nouveau sur React et maintenant je voudrais afficher un enregistrement dans le tableau et maintenant j'ai cette erreur. Aidez-moi, s'il vous plaît.

Appel de hook non valide. Les hooks ne peuvent être appelés qu'à l'intérieur du corps d'un composant de fonction. Cela peut se produire pour l'une des raisons suivantes: 1. Vous pouvez avoir des versions incompatibles de React et du moteur de rendu (tel que React DOM) 2. Vous pourriez enfreindre les règles des Hooks 3. Vous pouvez avoir plus d'une copie de React dans la même application Voir pour des conseils sur la façon de déboguer et de résoudre ce problème.

import React,{Component} from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';

const useStyles = makeStyles(theme => ({
    root: {
      width: '100%',
      marginTop: theme.spacing(3),
      overflowX: 'auto',
    },
    table: {
      minWidth: 650,
    },
  }));

class allowance extends Component{
    constructor(){
        super();
        this.state={
            allowances:[],
        };

    }

    componentWillMount() {
        fetch('http://127.0.0.1:8000/allowances')
        .then(data=>{  

            return data.json();      

        }).then(data=> {          

            this.setState({allowances : data});

            console.log("allowance state",this.state.allowances);
        })

    }



    render() {
        const classes = useStyles();
        return (
            <Paper className={classes.root}>
              <Table className={classes.table}>
                <TableHead>
                  <TableRow>
                    <TableCell>Allow ID</TableCell>
                    <TableCell align="right">Description</TableCell>
                    <TableCell align="right">Allow Amount</TableCell>
                    <TableCell align="right">AllowType</TableCell>

                  </TableRow>
                </TableHead>
                <TableBody>
                  {this.state.allowances.map(row => (
                    <TableRow key={row.id}>
                      <TableCell component="th" scope="row">
                        {row.AllowID}
                      </TableCell>
                      <TableCell align="right">{row.AllowDesc}</TableCell>
                      <TableCell align="right">{row.AllowAmt}</TableCell>
                      <TableCell align="right">{row.AllowType}</TableCell>                    
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </Paper>
          );}

}

export default allowance;


0 commentaires

14 Réponses :


8
votes

React linter suppose que chaque méthode commençant par une use tant que hooks et hooks ne fonctionne pas à l'intérieur des classes. en renommant const useStyles en tout autre élément qui ne commence pas par use comme const myStyles vous êtes const myStyles à partir.

Mise à jour:

makeStyles est une makeStyles hook et vous ne pouvez pas l'utiliser à l'intérieur des classes. vous pouvez utiliser l'API des composants stylisés. voir ici


3 commentaires

changé les styles d'utilisation en mystyles mais l'erreur se produit toujours.


Y a-t-il des documents suggérant que c'est vrai?


Oui, tu as raison. makeStyles est une API de hook et vous ne pouvez pas l'utiliser à l'intérieur des classes. voir ici



38
votes

Parce que vous Only Call Hooks from React Functions . Voir plus ici https://reactjs.org/docs/hooks-rules.html#only-call-hooks-from-react-functions . Convertissez simplement le composant de classe Allowance composant fonctionnel. La démo fonctionne ici https://codesandbox.io/s/amazing-poitras-k2fuf

const Allowance = () => {
  const [allowances, setAllowances] = useState([]);

  useEffect(() => {
    fetch("http://127.0.0.1:8000/allowances")
      .then(data => {
        return data.json();
      })
      .then(data => {
        setAllowances(data);
      })
      .catch(err => {
        console.log(123123);
      });
  }, []);

  const classes = useStyles();
  return (
    <Paper className={classes.root}>
      <Table className={classes.table}>
        <TableHead>
          <TableRow>
            <TableCell>Allow ID</TableCell>
            <TableCell align="right">Description</TableCell>
            <TableCell align="right">Allow Amount</TableCell>
            <TableCell align="right">AllowType</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {allowances.map(row => (
            <TableRow key={row.id}>
              <TableCell component="th" scope="row">
                {row.AllowID}
              </TableCell>
              <TableCell align="right">{row.AllowDesc}</TableCell>
              <TableCell align="right">{row.AllowAmt}</TableCell>
              <TableCell align="right">{row.AllowType}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </Paper>
  );
};

export default Allowance;


4 commentaires

Une chose que vous voulez vous demander, après avoir appelé setAllowances (data), les allocations devraient avoir des données, non? sinon, lorsque les quotas ont des données?


Oui. Après avoir appelé setAllowances (data). setAllowances fonctionnant comme this.setState({allowances: data})


J'étais un peu confus, après avoir appelé setAllowances (data), j'essaye comme console.log ("data", data); et cela a 3 enregistrements mais si j'essaye comme console.log ("allocation", allocations); ce n'est rien d'enregistrements. Puis-je savoir pourquoi? Vous pouvez essayer dans votre exemple de code.


Parce que setAllowances est asynchrone comme this.setState. Ainsi, vous enregistrez les allowances après setAllowances il enregistrera les old allowances .



2
votes

Vous pouvez convertir un composant de classe en hooks, mais Material v4 a un withStyles HOC. https://material-ui.com/styles/basics/#higher-order-component-api En utilisant ce HOC, vous pouvez garder votre code inchangé.


0 commentaires

2
votes

Hier, j'ai raccourci le code (je viens d'ajouter <Provider store={store}> ) et j'ai toujours ce problème d'appel de crochet non valide. Cela m'a fait soudainement réalisé l'erreur que j'avais faite: je n'ai pas installé le logiciel react-redux dans ce dossier.

J'avais installé ce logiciel dans l'autre dossier de projet, donc je ne savais pas que celui-ci en avait également besoin. Après l'avoir installé, l'erreur a disparu.


0 commentaires

1
votes

Je viens de commencer à utiliser des hooks et j'ai reçu l'avertissement ci-dessus lorsque j'appelais useEffect dans une fonction :

Ensuite, je dois déplacer useEffect en dehors de la fonction comme suit:

 const onChangeRetypePassword = async value => {
  await setRePassword(value);
//previously useEffect was here

  };
//useEffect outside of func 

 useEffect(() => {
  if (password !== rePassword) {
  setPasswdMismatch(true);

     } 
  else{
    setPasswdMismatch(false);
 }
}, [rePassword]);

J'espère que cela sera utile à quelqu'un!


0 commentaires

0
votes

Si tout ce qui précède ne fonctionne pas, en particulier si la dépendance est de grande taille (comme mon cas), la construction et le chargement prenaient au moins 15 secondes, il semble donc que le délai ait donné un faux message «Appel de hook non valide». Donc, ce que vous pouvez faire, c'est donner un peu de temps pour vous assurer que la construction est terminée avant de tester.


0 commentaires

9
votes

Vous pouvez utiliser "export par défaut" en appelant une fonction de flèche qui renvoie son React.Component en le passant par les accessoires d'objet de classe MaterialUI, qui à leur tour seront utilisés dans le composant render ().

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}

export default () => {
    const classes = useStyles();
    return (
        <AllowanceClass classes={classes} />
    )
}


0 commentaires

0
votes

Attrapé cette erreur: solution trouvée.

Pour une raison quelconque, il y avait 2 attributs onClick sur mon tag. Soyez prudent lorsque vous utilisez vos composants personnalisés ou ceux de certains d'entre eux, peut-être que certains d'entre eux ont déjà l'attribut onClick .


0 commentaires

3
votes

Pour moi, l'erreur appelait la fonction useState en dehors de la fonction par défaut exportée


0 commentaires

0
votes

Dans mon cas, j'essayais d'utiliser mdbreact sur Windows. Bien qu'il soit installé, mais j'obtenais l'erreur ci-dessus. J'ai dû le réinstaller et tout allait bien. Ça m'est arrivé une fois deux avec Antd Library


0 commentaires

4
votes

J'ai eu ce problème lorsque j'ai utilisé le npm link pour installer ma bibliothèque locale, que j'ai construite à l'aide de cra . J'ai trouvé la réponse ici . Ce qui dit littéralement:

This problem can also come up when you use npm link or an equivalent. 
In that case, your bundler might “see” two Reacts — one in application folder
and one in your library folder. Assuming 'myapp' and 'mylib' are sibling folders,
one possible fix is to run 'npm link ../myapp/node_modules/react' from 'mylib'.
This should make the library use the application’s React copy.

Ainsi, l'exécution de la commande: npm link ../../libraries/core/decipher/node_modules/react depuis mon dossier de projet a résolu le problème.


1 commentaires

Merci mon pote! tu as sauvé ma journée! Tous ceux qui utilisent des packages localement via le lien npm / yarn, suivez ceci!



-1
votes

Mon cas .... SOLUTION dans HOOKS

const [cep, setCep] = useState('');
const mounted = useRef(false);

useEffect(() => {
    if (mounted.current) {
        fetchAPI();
      } else {
        mounted.current = true;
      }
}, [cep]);

const setParams = (_cep) => {
    if (cep !== _cep || cep === '') {
        setCep(_cep);
    }
};


0 commentaires

0
votes

Cette erreur peut également se produire lorsque vous faites l'erreur de déclarer useDispatch de react-redux dans le mauvais sens: quand vous allez:
const dispatch = useDispatch au lieu de:
const dispatch = useDispatch(); (c'est-à-dire n'oubliez pas d'ajouter la parenthèse)


0 commentaires

0
votes

complétant le commentaire suivant

Pour ceux qui utilisent redux:

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}
    
const COMAllowanceClass = (props) =>
{
    const classes = useStyles();
    return (<AllowanceClass classes={classes} {...props} />);
};

const mapStateToProps = ({ InfoReducer }) => ({
    token: InfoReducer.token,
    user: InfoReducer.user,
    error: InfoReducer.error
});
export default connect(mapStateToProps, { actions })(COMAllowanceClass);


0 commentaires