如何在不违反钩子规则的情况下在 React 中调用 useContext?
How do you call useContext in React without breaking rules of hooks?
我正在尝试了解如何在上下文提供程序中为 Google 或 Github 调用登录函数。
在不破坏钩子规则的情况下,在 Next JS 中调用上下文提供程序的正确方法是什么?
// user.js
const Context = createContext();
const Provider = ({ children }) => {
const [user, setUser] = useState(supabase.auth.user());
const [isLoading, setIsLoading] = useState(true);
const router = useRouter();
useEffect(() => {
const getUserProfile = async () => {
const sessionUser = supabase.auth.user();
if (sessionUser) {
//removed for brevity
setUser({
...sessionUser,
...profile,
});
setIsLoading(false);
}
};
getUserProfile();
supabase.auth.onAuthStateChange(() => {
getUserProfile();
});
}, []);
const githubLogin = async () => {
await supabase.auth.signIn({
provider: "github",
});
};
const googleLogin = async () => {
await supabase.auth.signIn({
provider: "google",
});
};
const logout = async () => {
await supabase.auth.signOut();
setUser(null);
router.push("/");
};
const exposed = {
user,
googleLogin,
githubLogin,
logout,
isLoading,
};
return <Context.Provider value={exposed}>{children}</Context.Provider>;
};
export const useUser = () => useContext(Context);
export default Provider;
和我的登录页面
// login.js
const Login = () => {
const handleGithubLogin = () => {
const { githubLogin } = useUser();
useEffect(githubLogin, []);
}
const handleGoogleLogin = () => {
const { googleLogin } = useUser();
useEffect(googleLogin, []);
};
return (
<div>
<button onClick={handleGithubLogin}>Login with Github</button>
<button onClick={handleGoogleLogin}>Login with Google</button>
</div>
);
}
export default Login;
如何在不破坏钩子规则的情况下调用这些登录函数?从我的登录页面调用上下文提供程序的最佳方式是什么?
将对 useUser
的调用移动到组件的主体中,然后在需要时调用它 returns 的函数。我认为没有理由使用 useEffect
.
const Login = () => {
const { githubLogin, googleLogin } = useUser();
const handleGithubLogin = () => {
githubLogin();
}
const handleGoogleLogin = () => {
googleLogin();
}
return (
<div>
<button onClick={handleGithubLogin}>Login with Github</button>
<button onClick={handleGoogleLogin}>Login with Google</button>
</div>
);
}
// OR:
const Login = () => {
const { githubLogin, googleLogin } = useUser();
return (
<div>
<button onClick={githubLogin}>Login with Github</button>
<button onClick={googleLogin}>Login with Google</button>
</div>
);
}
我正在尝试了解如何在上下文提供程序中为 Google 或 Github 调用登录函数。
在不破坏钩子规则的情况下,在 Next JS 中调用上下文提供程序的正确方法是什么?
// user.js
const Context = createContext();
const Provider = ({ children }) => {
const [user, setUser] = useState(supabase.auth.user());
const [isLoading, setIsLoading] = useState(true);
const router = useRouter();
useEffect(() => {
const getUserProfile = async () => {
const sessionUser = supabase.auth.user();
if (sessionUser) {
//removed for brevity
setUser({
...sessionUser,
...profile,
});
setIsLoading(false);
}
};
getUserProfile();
supabase.auth.onAuthStateChange(() => {
getUserProfile();
});
}, []);
const githubLogin = async () => {
await supabase.auth.signIn({
provider: "github",
});
};
const googleLogin = async () => {
await supabase.auth.signIn({
provider: "google",
});
};
const logout = async () => {
await supabase.auth.signOut();
setUser(null);
router.push("/");
};
const exposed = {
user,
googleLogin,
githubLogin,
logout,
isLoading,
};
return <Context.Provider value={exposed}>{children}</Context.Provider>;
};
export const useUser = () => useContext(Context);
export default Provider;
和我的登录页面
// login.js
const Login = () => {
const handleGithubLogin = () => {
const { githubLogin } = useUser();
useEffect(githubLogin, []);
}
const handleGoogleLogin = () => {
const { googleLogin } = useUser();
useEffect(googleLogin, []);
};
return (
<div>
<button onClick={handleGithubLogin}>Login with Github</button>
<button onClick={handleGoogleLogin}>Login with Google</button>
</div>
);
}
export default Login;
如何在不破坏钩子规则的情况下调用这些登录函数?从我的登录页面调用上下文提供程序的最佳方式是什么?
将对 useUser
的调用移动到组件的主体中,然后在需要时调用它 returns 的函数。我认为没有理由使用 useEffect
.
const Login = () => {
const { githubLogin, googleLogin } = useUser();
const handleGithubLogin = () => {
githubLogin();
}
const handleGoogleLogin = () => {
googleLogin();
}
return (
<div>
<button onClick={handleGithubLogin}>Login with Github</button>
<button onClick={handleGoogleLogin}>Login with Google</button>
</div>
);
}
// OR:
const Login = () => {
const { githubLogin, googleLogin } = useUser();
return (
<div>
<button onClick={githubLogin}>Login with Github</button>
<button onClick={googleLogin}>Login with Google</button>
</div>
);
}