如何解决react中的“Invalid hook call”错误

问题描述 投票:0回答:4

我正在构建一个与 Formik 和 Yup 库反应的基本形式。该表单包含两个字段,电子邮件和密码;那应该从用户那里获取值并将其打印在控制台中。 现在我面临的问题是 Hook 调用错误,即使我没有在我的代码中使用任何 Hook!

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. ..
2. ..
3. ..

我已经对这个错误进行了研究,并尝试了它建议的所有可能方法。没有任何帮助。我只运行一个反应版本,据我所知我也没有违反钩子规则。谁能帮我检测这里的问题?

我的代码:

登录表单.js

const validationSchema = Yup.object().shape({
      email: Yup.string()
      .email("Email is not valid")
      .required("Email is required"),
      password: Yup.string()
        .min(6, "Minimum 6 characters required")
        .required("Password is required"),
    })

    class LoginForm extends React.Component {
      render() {
        return (
          <div>
            <Formik
              initialValues={{ email: "", password: "" }}
              validationSchema={validationSchema}
              onSubmit={(values) => this.props.handleFormUpdate(values)}
            >
              <Form>
                <label>
                  Email<Field type="email" name="email"></Field>
                </label>
                <ErrorMessage name="email" component="div"></ErrorMessage>
                <label>
                  Password<Field type="password" name="password"></Field>
                </label>
                <ErrorMessage name="password" component="div"></ErrorMessage>
                <button type="submit">Submit</button>
              </Form>
            </Formik>
          </div>
        );
      }
    }
    export default LoginForm;

App.js

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: "",
    };
  }
  handleFormUpdate(values) {
    console.log(values.email);
    console.log(values.password);
  }
  render() {
    return (
      <div>
        <LoginForm
          handleFormUpdate={this.handleFormUpdate.bind(this)}
        ></LoginForm>
      </div>
    );
  }
}

export default App;
reactjs react-hooks formik react-dom yup
4个回答
1
投票

这是因为

formik v2
是建立在 React Hooks 之上的。要解决这个问题,您需要将使用 formik 的类组件转换为功能组件。 这里是 formik.

的突破性变化的链接

[编辑] 或者你可以通过用高阶组件包装组件来使它与类组件一起工作

withFormik()


1
投票

所以现在我已经解决了这个问题。我只需要将类组件转换为功能组件,就像上面提到的 adel 一样。 LoginForm.js 的新结构是:

    const LoginForm = () => (
  <div>
    <Formik
      initialValues={{ email: "", password: "" }}
      validationSchema={validationSchema}
      onSubmit={(values) => this.props.handleFormUpdate(values)}
    >
      <Form>
        <label>
          Email<Field type="email" name="email"></Field>
        </label>
        <ErrorMessage name="email" component="div"></ErrorMessage>
        <label>
          Password<Field type="password" name="password"></Field>
        </label>
        <ErrorMessage name="password" component="div"></ErrorMessage>
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  </div>
);

错误消失了!


0
投票

我能够通过升级项目中的 React 版本来解决这个问题。检查项目上的 react 和 react-dom 的版本以及 node_modules 中的 formik。它们可能不同,这会导致无效挂钩调用错误。

您可能只是在类组件中使用 formik,这将不起作用。


0
投票
    React v.18.0 Compatible packages for Formik with material UI (mui) needs to be get installed.
    
    Hence, This issue can be resolved using "formic-mui" package. 
    
    steps:
    
    1. need to install packages "formik formik-mui @mui/material @emotion/react @emotion/styled"
    
    2. then follow guidelines from here: [https://stackworx.github.io/formik-mui/docs/guide/getting-started][1]
    
    3. After modifications, your code will look like this:
    
     
    
     
    import * as React from 'react';
    import { Formik, Field, Form, FormikHelpers } from 'formik';
    import { Button, Grid, LinearProgress } from '@mui/material';
    import * as yup from 'yup';
    import { TextField } from 'formik-mui';
    import TextareaAutosize from '@material-ui/core/TextareaAutosize/TextareaAutosize';
    
    interface Values {
      email: string;
      password: string;
    }
    
    const CustomerDetails = () => {
      return (
        <div>
          <h1>Customer Details</h1>
    
          <Formik
            initialValues={{
              email: '',
              password: '',
            }}
            validate={(values) => {
              const errors: Partial<Values> = {};
              if (!values.email) {
                errors.email = 'Required';
              } else if (
                !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
              ) {
                errors.email = 'Invalid email address';
              }
              return errors;
            }}
            onSubmit={(values, { setSubmitting }) => {
              setTimeout(() => {
                setSubmitting(false);
                alert(JSON.stringify(values, null, 2));
              }, 500);
            }}
          >
            {({ submitForm, isSubmitting }) => (
              <Form>
                <Grid container spacing={1}>
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      name="customername"
                      type="customername"
                      label="Customer Name"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={12} sm={4}>
                    <Field
                      component={TextField}
                      type="telephone"
                      label="Telephone"
                      name="telephone"
                      fullWidth
                    />
                  </Grid>
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      type="dob"
                      label="Date of Birth"
                      name="dob"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={12} sm={4}>
                    <Field
                      component={TextField}
                      type="alttelephone"
                      label="Alt Telephone"
                      name="alttelephone"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={12} sm={4}>
                    <Field
                      component={TextField}
                      type="alttelephone"
                      label="Alt Telephone"
                      name="alttelephone"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      name="email"
                      type="email"
                      label="Email"
                      fullWidth
                    />
                  </Grid>
    
                  <Grid item xs={4} sm={4}>
                    <Field
                      component={TextField}
                      name="password"
                      type="password"
                      label="Password"
                      fullWidth
                    />
                  </Grid>
    
                  {isSubmitting && <LinearProgress />}
    
                  <Grid item xs={12} sm={12}>
                    <Button
                      variant="contained"
                      color="primary"
                      disabled={isSubmitting}
                      onClick={submitForm}
                    >
                      Submit
                    </Button>
                  </Grid>
                </Grid>
              </Form>
            )}
          </Formik>
        </div>
      );
    };
    
    export default CustomerDetails;




[![enter image description here][1]][1]

此外,我的 Package.json 看起来像这样:

© www.soinside.com 2019 - 2024. All rights reserved.