Javascript 尽管代码运行,但arrow函数组件内部的钩子调用无效

Javascript 尽管代码运行,但arrow函数组件内部的钩子调用无效,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在学习react,并尝试在使用单击show Toast按钮时显示一个简单的弹出窗口。但是,我收到了以下错误: Error in /turbo_modules/react-dom@16.13.1/cjs/react-dom.development.js (12408:27) Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for o

我正在学习react,并尝试在使用单击
show Toast
按钮时显示一个简单的弹出窗口。但是,我收到了以下错误:

Error in /turbo_modules/react-dom@16.13.1/cjs/react-dom.development.js (12408:27)
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
虽然我不习惯用钩子,但我假设它很简单。该错误表示挂钩只能在功能组件的主体内部调用,因此:

  • 从技术上讲,功能组件的主体在哪里?我假设我把这个注释放在哪里:
    //这里是功能组件的主体
  • 为什么JS控制台中也会出现此错误:
    无法对未安装的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务
  • 我怎样才能让弹出窗口显示出来?控制台中会显示
    console.log('click')
    ,因此我认为是后续的
    toast
    代码不正确
  • 这是一个

    代码如下:

    import React from "react";
    import { useForm } from "react-hook-form";
    import { useToast } from "@chakra-ui/core";
    
    const App = () => {
      const { register, handleSubmit, watch, errors } = useForm();
      //const toast = useToast();
      const onSubmit = data => {
          console.log('data', data);
        };
    
      // body of functional component here?
    
      const toastTest = () => 
        {
          const toast = useToast();
          return (
          <button
            onClick={() =>
              {
                console.log('click');
                toast({
                  title: "Account created.",
                  description: "We've created your account for you.",
                  status: "success",
                  duration: 9000,
                  isClosable: true,
                })
              }
            }
          >
            Show Toast
          </button>
        )
      };
    
      console.log(watch("example"));
    
      return (
        <>
    
        {toastTest()}
    
        <form onSubmit={handleSubmit(onSubmit)}>
          <input name="example" defaultValue="test" ref={register} />
          
          <input name="exampleRequired" ref={register({ required: true })} />
          {errors.exampleRequired && <span>This field is required</span>}
          
          <input type="submit" />
        </form>
        </>
      );
    }
    
    export default App
    
    从“React”导入React;
    从“react hook form”导入{useForm};
    从“@chakra ui/core”导入{useToast}”;
    常量应用=()=>{
    常量{register,handleSubmit,watch,errors}=useForm();
    //const toast=useToost();
    const onSubmit=data=>{
    console.log('data',data);
    };
    //功能部件的主体在这里?
    常数toastest=()=>
    {
    const toast=useToost();
    返回(
    {
    console.log('click');
    吐司({
    标题:“已创建帐户。”,
    描述:“我们已经为您创建了帐户。”,
    状态:“成功”,
    时长:9000,
    不公开:是的,
    })
    }
    }
    >
    敬酒
    )
    };
    log(监视(“示例”));
    返回(
    {toastest()}
    {errors.exampleRequired&&此字段为必填项}
    );
    }
    导出默认应用程序
    

    我从其他用户那里看到过类似的帖子,但无法实现。任何关于hooks的初学者建议都将不胜感激,谢谢。

    从技术上讲,您违反了规则。您应该将
    useToast
    从名为
    toast test的函数体移出到函数组件的根目录中

    请参阅下面我建议的解决方案:

    const App = () => {
      const toast = useToast(); // useToast moved here from the function
      const { register, handleSubmit, watch, errors } = useForm();
    
      const onSubmit = data => {
          console.log('data', data);
      }
    
      const toastTest = () => 
         // please notice useToast is removed from here
         // ... rest of the function's body
      }
    
      return <> { /* your return */ }</>
    }
    
    const-App=()=>{
    const toast=useToos();//useToos从函数移到这里
    常量{register,handleSubmit,watch,errors}=useForm();
    const onSubmit=data=>{
    console.log('data',data);
    }
    常数toastest=()=>
    //请注意,UseToos已从此处删除
    //…函数体的其余部分
    }
    返回{/*您的返回*/}
    }
    
    Move
    const toast=useToost()退出
    toastest
    运行命令
    warn install
    并尝试。谢谢,但我已尝试将其移到外部,但仍无法正常工作-请参阅此新的stackBlitz演示:谢谢,但我已尝试将其移到外部,但仍无法正常工作-请参阅此新的stackBlitz演示: