Right now, I have a lot of my auth functions inside my screen components and I want to extract them into a handlers file. But, they rely on setting the state for some loading and results states.
How can I properly pass a setState as an argument to a function?
const handleSignIn = async (email: string) => {
setLoading(true);
const { error } = await supabase.auth.signInWithOtp({
email: email,
});
if (error) {
console.log(error);
setLoading(false);
} else {
setLoading(false);
navigation.navigate('VerifyOtp', { email: userEmail });
}
};
So in this case, I want to refactor the function so it takes another argument of setLoading
for example. How do I achieve this?
Thank you in advance.
CodePudding user response:
It's possible to pass just callback as in another answer, but I would prefer another way of doin this:
function useSignIn() {
const [loading, setLoading] = useState(false);
const handleSignIn = useMemo(async (email: string) => {
setLoading(true);
const { error } = await supabase.auth.signInWithOtp({
email: email,
});
if (error) {
console.log(error);
setLoading(false);
} else {
setLoading(false);
navigation.navigate('VerifyOtp', { email: userEmail });
}
}, [setLoading]);
return [loading, handleSignIn];
}
By the way, I'm not sure what { email: userEmail }
is. Is userEmail
misprint (should be email
instead) or some global variable or comes from another hook? It should be somehow handled in useMemo
deps.
CodePudding user response:
The most straight forward way to go is dependency injection.
export const handleSignInFactory = (setLoading) => {
const handleSignIn = async (email: string) => {
setLoading(true);
const { error } = await supabase.auth.signInWithOtp({
email: email,
});
if (error) {
console.log(error);
setLoading(false);
} else {
setLoading(false);
navigation.navigate('VerifyOtp', { email: userEmail });
}
};
return handleSignIn;
}
Now in your react component:
function MyComp(props) {
const [loading, setLoading] = useState(false);
const handleSignIn = handleSignInFactory(setLoading);
// ...
return <button onClick={handleSignIn}>Sign In</button>;
}
CodePudding user response:
You can make your own custom hook and extract it into its own file
function useAuth() {
const [loading, setLoading] = useState(false);
async function signIn() {
setLoading(true);
const { error } = await supabase.auth.signInWithOtp({
email: email,
});
if (error) {
console.log(error);
setLoading(false);
} else {
setLoading(false);
navigation.navigate('VerifyOtp', { email: userEmail });
}
}
return [loading, signIn];
}