代码之家  ›  专栏  ›  技术社区  ›  Swarley Gnome

我如何将依赖关系传递给自定义钩子,并表现得像useEffect?

  •  1
  • Swarley Gnome  · 技术社区  · 1 年前

    如何触发 useEffect 里面 useRedirect 如果给定,请再次自定义挂钩 deps (或依赖关系)变化?

    代码:

    const OnboardingLayout = () => {
        const { user } = useUserContext()
    
        useRedirect("/c", () => {
            if (user) {
                Object.values(user.onboarding).every(e => e)
            }
        }, [user])
    
        return (
            <Outlet />
        )
    }
    
    export const useRedirect = (path, validator = () => true, deps = []) => {
        const navigate = useNavigate()
    
        useEffect(() => {
            if (validator()) {
                navigate(path)
            }
        }, [path, navigate, validator, ...deps])
    }
    

    这个 使用重定向 在里面 OnboardingLayout 未按预期工作,因为如果 user 对象现在是真实的(从 null )the 使用效果 使用重定向 即使我已经传递了一个依赖项,自定义钩子也不会再次触发。此外,传播 deps 使用效果 eslint给了我一个警告,说:, “React Hook useEffect的依赖数组中有一个spread元素。这意味着我们无法静态验证您是否传递了正确的依赖关系。” .

    1 回复  |  直到 1 年前
        1
  •  1
  •   AKX Bryan Oakley    1 年前

    对于ESlint警告,你无能为力——这是完全正确的,因为它现在无法帮助你(没关系,这只是一个提醒你小心dep数组的警告)。

    快速浏览一下,你的逻辑看起来很好,只是你的 validator() 实现永远不会返回任何东西,但 undefined .

    怎么样

    useRedirect("/c", () => {
      return user && Object.values(user.onboarding).every(e => e);
    }, [user])
    

    相反?

    (顺便说一句,使用TypeScript会捕捉到这一点,因为一个不返回 boolean 不会通过 validator: () => boolean = () => true ... :) )