Javascript 自定义挂钩中带有ref的useEffect缺少依赖项警告

Javascript 自定义挂钩中带有ref的useEffect缺少依赖项警告,javascript,reactjs,react-hooks,eslint,ref,Javascript,Reactjs,React Hooks,Eslint,Ref,在启用了deps规则的React Typescript中,当我定义一个ref并在效果内部使用它时,linter可以使用它: const stringRef: RefObject<string> = useRef("Hello World!"); useEffect(() => { console.log(stringRef.current); }, []) // no warning, the linter detects that I'm usi

在启用了deps规则的React Typescript中,当我定义一个ref并在效果内部使用它时,linter可以使用它:

const stringRef: RefObject<string> = useRef("Hello World!");
  
useEffect(() => {
  console.log(stringRef.current);
}, []) // no warning, the linter detects that I'm using a ref
const-stringRef:reObject=useRef(“你好,世界!”);
useffect(()=>{
控制台日志(stringRef.current);
},[])//没有警告,林惇检测到我正在使用ref
但是,当我将效果放在自定义挂钩中时,linter抱怨我应该在依赖项数组中包含ref:

const stringRef: RefObject<string> = useRef("Hello World!");
  
useCustomHook(stringRef);

// in another-file.ts
const useCustomHook = (ref: RefObject<string>) => {
  useEffect(() => {
    console.log(ref.current);
  }, []) // ESLint: React Hook useEffect has a missing dependency: 'ref'. Either include it or remove the dependency array.(react-hooks/exhaustive-deps)
}
const-stringRef:reObject=useRef(“你好,世界!”);
useCustomHook(stringRef);
//在另一个-file.ts中
const useCustomHook=(ref:reObject)=>{
useffect(()=>{
控制台日志(参考当前);
},[])//ESLint:React Hook useffect缺少依赖项:“ref”。请包含它或删除依赖项数组。(React hooks/deps)
}
从语义上讲,没有任何变化,但是,linter不承认ref是一个重新对象(即使我这样键入它)

现在的大问题是:如何让linter知道给定的依赖项不需要包含在依赖项数组中而不抑制警告?

对我来说,这是一个主要的缺点,这是不可能的,因为我不能将我的效果转换成定制的挂钩,而不让衣帽匠抱怨


谢谢您的帮助。

您可以使用//eslint disable next line react hooks/deps禁用该规则,否则您可以将ref移动到useffect中

useEffect(() => {
   // other code
   ...

   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 

useffect1useffect2之间的区别在于
stringRef
是一个常数,因此根据定义const不会改变,但在示例2中
ref
是一个可以改变的变量,因此,您必须将参数作为依赖项添加。

您不能直接配置它

linter(
eslint
)是一个静态代码分析器。它只分析文本模式而不编译代码,也就是说它不知道所写内容的“含义”

例如,它看到“
使用***()
”模式并认为它是一个自定义钩子,然后用钩子模式的规则验证它,比如在
if
语句中没有这样的文本

你自己看看:

提醒:自定义钩子是一个前缀为“use”的函数和一个使用钩子的函数

//不是自定义挂钩,只是一个带有“use”前缀的函数
const useConsole=()=>console.log(“hello”);
//正常功能
constloghello=()=>console.log(“hello2”);
常量组件=()=>{
如果(真){
//警告-有条件地调用React钩子
使用控制台();
//嗯
logHello();
}
返回示例;
};

但是,您始终可以在同一范围内识别
重新对象
使用效果


从Typescript编译器的角度来看,它没有违反任何规定,因为用例与
useffect
类型匹配。

正如前面所说的,我不想取消警告,因为这样我可能会错过将来需要添加的依赖项。我很好奇为什么会这样说。如果此处的ref.current是一个非基元而不是类似基元的字符串,您是否看到了相同的行为?@lakshytakur当ref是一个对象或dom ref(HTMLElement)时,总是显示警告。但是,正如alredy所说,只有在自定义效果(在额外文件中)上,当ref不在效果的周围范围内(而是作为参数传递)时,才可以使用。如果ref在效果的周围范围内,则不会显示警告
ref
useRef
返回的对象是否稳定?您可以在自定义效果中将其安全地用作依赖项我同意@thedude,如果您确信ref是稳定的(它应该是一个ref),那么只需将其放入依赖项数组中即可。除非ref本身被重新声明,否则它不会触发useffect,这应该只发生在组件初始渲染时。如果您对依赖关系数组的稳定性有信心,请不要害怕将其放入依赖关系数组。感谢您的输入,我认为会有一种更聪明的方法来满足linter的要求。通过将ref添加为依赖项,即使它是ref I,也会“污染”依赖项数组,并分散对必须包含的依赖项的注意力。但是,嘿,我想我必须接受这个缺点!
// NOT A CUSTOM HOOK, just a function with 'use' prefix
const useConsole = () => console.log("hello");

// Normal function
const logHello = () => console.log("hello2");

const Component = () => {
  if (true) {
    // Warning - React hook is called conditionally
    useConsole();

    // OK
    logHello();
  }
  return <>Example</>;
};