You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复ESLint报错:React Hook React.useEffect缺少依赖项

解决useEffect依赖toast导致无限执行且不违反ESLint规则的问题

你遇到的问题核心是useToast()返回的实例引用可能在组件每次渲染时变化,直接添加到useEffect依赖会触发无限回调,但跳过依赖又违反ESLint的exhaustive-deps规则。这里有几种可靠的解决方式:

方法一:用useRef持久化toast实例

通过useRef保存toast的引用,确保在组件生命周期内引用稳定,同时让useEffect只关注firebaseAuthError的变化:

function SignUpForm() {
  const navigation = useNavigation<NativeStackScreenProps<RootStackParamList, "Signup">["navigation"]>()
  const dispatch = useAppDispatch()
  const firebaseAuthError = useAppSelector((state) => state.auth.error)
  const toast = useToast()
  const toastRef = React.useRef(toast)

  // 每次toast更新时同步ref
  React.useEffect(() => {
    toastRef.current = toast
  }, [toast])

  const [formState, setFormState] = useState<Form>({
    email: "",
    emailError: "",
    password: "",
    passwordError: "",
    isPasswordVisible: false,
    passwordConfirm: "",
    passwordConfirmError: "",
    isPasswordConfirmVisible: false,
  })

  React.useEffect(() => {
    if (firebaseAuthError) {
      toastRef.current.show({
        title: "Authentication error",
        description: firebaseAuthError,
        duration: 2000,
      })
    }

    return () => toastRef.current.closeAll()
  }, [firebaseAuthError])
}

这种方式既满足了ESLint的依赖检查要求,又避免了因toast引用变化导致的无限执行。

方法二:包装toast调用为稳定的回调

如果toast.show和toast.closeAll方法的引用是稳定的,可以用useCallback包装调用逻辑,再添加到useEffect依赖中:

function SignUpForm() {
  const navigation = useNavigation<NativeStackScreenProps<RootStackParamList, "Signup">["navigation"]>()
  const dispatch = useAppDispatch()
  const firebaseAuthError = useAppSelector((state) => state.auth.error)
  const toast = useToast()

  const showAuthError = React.useCallback((error) => {
    toast.show({
      title: "Authentication error",
      description: error,
      duration: 2000,
    })
  }, [toast])

  const closeToasts = React.useCallback(() => {
    toast.closeAll()
  }, [toast])

  const [formState, setFormState] = useState<Form>({
    email: "",
    emailError: "",
    password: "",
    passwordError: "",
    isPasswordVisible: false,
    passwordConfirm: "",
    passwordConfirmError: "",
    isPasswordConfirmVisible: false,
  })

  React.useEffect(() => {
    if (firebaseAuthError) {
      showAuthError(firebaseAuthError)
    }

    return closeToasts
  }, [firebaseAuthError, showAuthError, closeToasts])
}

这种方式通过useCallback确保回调的引用稳定,只有当toast实例真的变化时才会更新回调,避免不必要的useEffect触发。

额外提示

如果你的toast库支持全局调用(无需通过useToast获取实例),可以直接使用全局API,这样完全不需要依赖组件内的toast实例,从根源上解决问题。

内容的提问来源于stack exchange,提问作者suchcodemuchwow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:01:20