Warning: An unhandled error was caught from submitForm() Error:

4.8k Views Asked by At

I am starting a project with react,nextjs and typescript, I am trying to submit a form to my backend, but when trying to use the function for the call to the function generated with @ urql-codegen I am getting the following warning, formik.esm.js:925 Warning: An unhandled error was caught from submitForm() Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

and the query but the query does'n trigger

where my error can be i dont know what to do

The code below

   import React from 'react';
import { Formik, Form, Field, FormikHelpers } from 'formik';
import Wrapper from '../components/Wrapper';
import InputField from '../components/InputField';
import { toErrorMap } from '../utils/toErrorMap';
import { useRouter } from 'next/router';
import { createUrqlClient } from '../utils/createUrqlClient';
import { withUrqlClient } from "next-urql"
import { Button, LinearProgress, Grid } from '@material-ui/core';
import Paper from '@material-ui/core/Paper';
import { TextField } from 'formik-material-ui';
import { makeStyles } from '@material-ui/core/styles';
import Avatar from '@material-ui/core/Avatar';
import Typography from '@material-ui/core/Typography';
//import { useLoginUsuarioQuery } from '../generated/graphql';
import { useQuery } from 'urql';
import { useUserByIdQuery } from '../generated/graphql';

const Login: React.FC<{}> = ({ }) => {
  const router = useRouter();
  const classes = useStyles();
  
  const submitForm = ({username,password}) => {
    const [{data}] = useUserByIdQuery({variables:{id:1}});
    console.log(data);
  }    

  return (
    <Grid container component="main" className={classes.root}>
      <Grid item xs={false} sm={4} md={7} className={classes.image}></Grid>
      <Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square >
        <div className={classes.paper}>
          <Avatar className={classes.avatar}>
            M
                </Avatar>
          <Typography component="h1" variant="h5">
            Ingresar
                </Typography>
          <Formik
            initialValues={{ username: '', password: '' }}
            onSubmit={(values) => {submitForm(values)}}
          >
            {({ isSubmitting }) => (
              <Form className={classes.form}>
                <Field
                  component={TextField}
                  name="username"
                  type="text"
                  label="username"
                  variant="outlined"
                  className={classes.form}
                />
                <br />
                <Field
                  component={TextField}
                  type="password"
                  label="Password"
                  name="password"
                  variant="outlined"
                  className={classes.form}
                />
                {isSubmitting && <LinearProgress />}
                <br />
                <Button
                  variant="contained"
                  color="primary"
                  disabled={isSubmitting}
                  type="submit"
                  className={classes.form}

                >
                  Submit
                </Button>
              </Form>
            )}
          </Formik>
        </div>
      </Grid>
    </Grid>


  );

}


export default withUrqlClient(createUrqlClient)(Login)
1

There are 1 best solutions below

0
On BEST ANSWER

It looks like you're calling useUserByIdQuery inside submitForm, which is a callback. By the naming convention the former is a hook which can only be called directly by your component, as per React's "Rules of Hooks" https://reactjs.org/docs/hooks-rules.html

I see that you're using a query as generated by (maybe) GraphQL Code Generator, which gives you a hook to use for getting a "User by ID". I assume that you'd want to make this call imperatively when a user submits this login form. To achieve this, depending on what you'd like to do, you'll either have to make your query imperatively or add some state.

The former is more likely if you're dealing with login, as I suppose in the future you may want to have a login mutation. In this case you can either use client.query(...).toPromise() using the urql client, but you must pass the query manually, or you can use useUserByIdQuery and pass pause: true as a parameter and use the returned executeQuery function to give it an ID.