【问题标题】:Call of hooks is inside of functional component give error Hooks can only be called inside of the body of a function component挂钩的调用在功能组件内部给出错误挂钩只能在功能组件的主体内部调用
【发布时间】:2022-01-06 09:05:46
【问题描述】:

我有用于翻译的组件语言

const Language = (props: IOwnProps) => {
    // error is in next line for useSelector 
    const language = useSelector(
        (state: IState) => state.currentLang
    );
    
    return getTranslations(
        props.languageString
    );
};

在表单中我使用 formik 进行验证

const validationSchema = () => {
    const requiredFirstName = Language({
        languageString: firstNameRequired,
    });
    return yup.object({
        firstName: yup
            .string()
            .required(requiredFirstName)
    });
};

这里是表单组件

const UserForm = ({
    userData: userData
    setErrorIndex,
}: UserFormProps) => {
    const formik = useFormik({
        initialValues: {
            userData: userData.firstName,
        },
        validationSchema,
        onSubmit: (values) => {
            const playerDataLocal = {
                firstName: values.firstName,
            };
            handleSubmit(playerDataLocal);
        },
    });

    return (
        <form onSubmit={formik.handleSubmit}>
            <TextField
                id="firstName"
                name="firstName"
                label="First Name *"
                defaultValue={formik.values.firstName}
                onChange={formik.handleChange}
                error={formik.touched.firstName && Boolean(formik.errors.firstName)}
                helperText={formik.touched.firstName && formik.errors.firstName}
                fullWidth
            />
        </form>
    );
};
export default UserForm;

在带有语言的验证模式行中给出错误: 无效的挂钩调用。 Hooks 只能在函数组件内部调用。

Language 的调用来自validationSchema,这是一个功能组件 错误的调用堆栈位于useSelector 的行中,来自Language validationSchema 的调用在“useFormik”内部可能是这个问题吗? 有什么想法吗?

【问题讨论】:

  • 你必须用前缀use命名你的钩子,例如useLanguageuseValidationSchema.
  • 看起来像eslint-plugin-react-hooks 认为你违反了钩子规则,因为validationSchema 不以大写字母或use 前缀开头。
  • 或在父组件 UserForm 中调用 useSelector 并将其作为道具转发 - 您不必使用 use 重命名
  • Language 看起来不像组件?

标签: javascript reactjs formik


【解决方案1】:

这是因为 validationSchema 不是 React 组件。您只能在功能组件或另一个钩子中使用钩子,并且由于 validationSchema 返回的不是 JSX 或另一个组件,因此它不属于这两者(参见 React docs for Hook Rules)。

您可能希望将挂钩调用移动到 UserForm 内,然后将结果作为参数传递给 validationSchema

【讨论】:

  • 感谢您的回答,它在用户窗体内部时有效,但现在用户窗体是非常大的组件:)
  • 不幸的是,带有很多钩子的组件变大而无法拆分是不可避免的。我目前在一个 1200 行长的组件中工作......
  • 你也可以从其他钩子中调用钩子,这个重要的细节需要明确。
  • @fast-reflexes 你有链接到它说的文档吗?我找不到参考资料,但如果我得到它,我会更新我的答案以包含它
  • @Tom 除了做过一百万次之外:reactjs.org/docs/…。我想说这就是自定义钩子的力量所在。否则我们可以让它成为一个常规函数。 OP 甚至在 Language 中调用了另一个钩子,这实际上是一个名称不正确的钩子(或者它可能是一个 React 组件,无法从上下文中看到)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 2021-09-13
  • 2020-07-22
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多