【问题标题】:How to use react hook as common component with typescript如何将反应钩子用作打字稿的通用组件
【发布时间】:2021-04-28 04:26:13
【问题描述】:

我有一个 SnackBar.ts 文件如下

import { useSnackbar } from 'notistack';

const SnackBar = (message:string, isError?:boolean) => {
  const { enqueueSnackbar } = useSnackbar();
  return enqueueSnackbar(message, {
    anchorOrigin: {
      horizontal: 'right',
      vertical: 'top'
    },
    variant: isError ? 'error' : 'success',
    style: { whiteSpace: 'pre-line' }
  });
};

export default SnackBar;

所以我开始在我的组件 tsx 中使用它,如下所示

    import { FC, useEffect, useState } from 'react';
    import { SnackBar } from '../../snackbar';

    const userEditForm: FC = (props) => {
    const mySnack = SnackBar;
    
    useEffect(() => {
        console.log('error');
        if (!loading && submitForm) {
          if (!error) {
            mySnack('user updated');
          } else {
            mySnack(error, true);
          }
        }
      }, [error, loading, submitForm]);
       
     return ( <MyComponent /> );
}

我收到此错误“Error: Invalid hook call. Hooks can only be called inside of the body of a function component

错误来自这一行mySnack('user updated');

我想要做的就是使用enqueueSnackbar 作为共享方法。 我怎样才能在打字稿中做到这一点?

【问题讨论】:

  • 请附上minimal reproducible example。看起来您正在文件根目录调用钩子,这可以解释错误,还是只是一个不完整的示例?

标签: reactjs typescript react-hooks notistack


【解决方案1】:

错误正是它所说的。根据 sn-p,您正在尝试在错误导入下方的函数之外调用 useEffect()

试试这个,

import { SnackBar } from '../../snackbar';


const SomeComponent = () => {

const mySnack = SnackBar;

callSnack(){
console.log('error');
    if (!loading && submitForm) {
      if (!error) {
        mySnack('user updated');
      } else {
        mySnack(error, true);
      }
    }
}


useEffect(() => {
    callSnack();
  }, [error, loading, submitForm]);

return <div> Somehting </div>;
}

这应该可以解决您的问题,但不确定您为什么要重新分配给mySnack,您可以直接致电SnackBar(' ')

此外,为了获得最佳实践,请使用扩展名 tsx 命名包含 React 组件的文件。

【讨论】:

  • 他在useEffect 内部调用mySnack('user updated');,这是另一种会引发他所遇到的错误的情况。
  • 但是useEffect不是didComponentMount调用而是依赖改变调用,所以应该没问题吧?因为它不会导致构建无限循环?
  • @sameerkashyap 我尝试了 SnackBar() 并尝试将 ts 文件更改为 tsx。还是一样的问题
  • 你在函数内部使用了钩子吗? @AMendis 否则,请使用错误行号更新您的问题,以便我们获得更好的图片。
  • @sameerkashyap 更新了问题。我打电话给 mySnack('user updated');内部使用效果
猜你喜欢
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2021-06-30
  • 2018-11-17
  • 2021-07-09
  • 2020-08-09
  • 1970-01-01
相关资源
最近更新 更多