Authenticating Users via OTP
This guide assumes you have already followed the Setup Guide and have set up the Alchemy Account Provider using this guide. Please refer to the guides above for more information on how to properly setup your project.
For a complete example of how we can setup a project and use the various available authentication methods, please refer to our quickstart example.
Authenticating a user is easy using the useAuthenticate()
hook from the @account-kit/react-native
package.
Set the Email Mode to One Time Password (OTP)
in your Smart Wallets Dashboard
This is the default mode for email authentication. Only follow these steps if
you had previously set the email mode to Magic Link
.
In your Alchemy Accounts Dashboard:
-
Navigate to the Smart Wallets tab
-
Select the config you would be using for your project and click the Edit button
-
Scroll down to the Email Mode options in the Email section and select One Time Password (OTP)
-
Click the Save Changes button
Send a One-Time Password (OTP) to a User
To send an OTP to a user’s email, use the authenticate()
function from the useAuthenticate()
hook with the type
set to email
and the emailMode
set to otp
.
import { function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate } from "@account-kit/react-native";
import React, { function useState<S>(initialState: S | (() => S)): [S, React.Dispatch<React.SetStateAction<S>>] (+1 overload)Returns a stateful value, and a function to update it.
useState } from "react";
import { type Alert = AlertStatic
const Alert: AlertStaticAlert, class ViewView, class TextText, class TextInputTextInput, class ButtonButton, const Pressable: React.ForwardRefExoticComponent<PressableProps & React.RefAttributes<View>>Pressable } from "react-native";
function function SignInWithOtp(): JSX.ElementSignInWithOtp() {
const { const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate } = function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate();
const [const email: stringemail, const setEmail: React.Dispatch<React.SetStateAction<string>>setEmail] = useState<string>(initialState: string | (() => string)): [string, React.Dispatch<React.SetStateAction<string>>] (+1 overload)Returns a stateful value, and a function to update it.
useState("");
const const handleUserSignInWithOtp: () => voidhandleUserSignInWithOtp = () => {
try {
const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => voidauthenticate({
email: stringemail,
type: "email"type: "email",
});
// OTP sent to the user's email. Prompt the user to enter the OTP into your app.
} catch (function (local var) e: unknowne) {
const Alert: AlertStaticAlert.AlertStatic.alert: (title: string, message?: string, buttons?: AlertButton[], options?: AlertOptions) => voidalert("Error sending OTP Code. Check logs for more details.");
var console: ConsoleThe console
module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream. * A global console
instance configured to write to process.stdout
and process.stderr
. The global console
can be used without importing the node:console
module.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O
for more information.
Example using the global console
:
const name = 'Will Robinson'; console.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ```
Example using the `Console` class:
```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err);
myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson'; myConsole.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
console.Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)log("Error seding OTP CODE: ", function (local var) e: unknowne);
}
};
return (
<class ViewView>
<class TextText>Enter Your Email to Sign In</class TextText>
<class ViewView>
<class TextInputTextInput
value?: string | undefinedThe value to show for the text input. TextInput is a controlled component, which means the native value will be forced to match this value prop if provided. For most uses this works great, but in some cases this may cause flickering
one common cause is preventing edits by keeping value the same. In addition to simply setting the same value, either set editable=false, or set/update maxLength to prevent unwanted edits without flicker.
value={const email: stringemail}
onChangeText?: ((text: string) => void) | undefinedCallback that is called when the text input's text changes. Changed text is passed as an argument to the callback handler.
onChangeText={(val: stringval) => const setEmail: (value: React.SetStateAction<string>) => voidsetEmail(val: stringval.String.toLowerCase(): stringConverts all the alphabetic characters in a string to lowercase.
toLowerCase())}
placeholder?: string | undefinedThe string that will be rendered before text input has been entered
placeholder="[email protected]"
/>
<const Pressable: React.ForwardRefExoticComponent<PressableProps & React.RefAttributes<View>>Pressable PressableProps.onPress?: ((event: GestureResponderEvent) => void) | null | undefinedCalled when a single tap gesture is detected.
onPress={const handleUserSignInWithOtp: () => voidhandleUserSignInWithOtp}>
{({ pressed: booleanpressed }) => (
<class ViewView
style?: StyleProp<ViewStyle>style={[
{
ViewStyle.opacity?: AnimatableNumericValue | undefinedopacity: pressed: booleanpressed ? 0.5 : 1,
TransformsStyle.transform?: string | readonly (({
perspective: AnimatableNumericValue;
} & {
rotate?: undefined;
rotateX?: undefined;
rotateY?: undefined;
rotateZ?: undefined;
scale?: undefined;
scaleX?: undefined;
... 5 more ...;
matrix?: undefined;
}) | ... 11 more ... | ({
...;
} & {
...;
}))[] | undefinedtransform: [
{
scale: AnimatableNumericValuescale: pressed: booleanpressed ? 0.98 : 1,
},
],
},
]}
>
<class TextText>Sign In</class TextText>
</class ViewView>
)}
</const Pressable: React.ForwardRefExoticComponent<PressableProps & React.RefAttributes<View>>Pressable>
</class ViewView>
</class ViewView>
);
}
Prompt the User to enter the One-Time Password to complete authentication
The user will receive an email with a one-time password (OTP) to enter into your app.
Provide a means for the user to enter the OTP into your app and then call the authenticate()
function from the useAuthenticate()
hook passing the OTP code to the otpCode
parameter, and the type
set to otp
.
import { function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate } from "@account-kit/react-native";
import React, { function useState<S>(initialState: S | (() => S)): [S, React.Dispatch<React.SetStateAction<S>>] (+1 overload)Returns a stateful value, and a function to update it.
useState } from "react";
import { type Alert = AlertStatic
const Alert: AlertStaticAlert, class ViewView, class TextText, class TextInputTextInput, class ButtonButton, const Pressable: React.ForwardRefExoticComponent<PressableProps & React.RefAttributes<View>>Pressable } from "react-native";
function function VerifyOtp(): JSX.ElementVerifyOtp() {
const { const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate } = function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate();
const [const otpCode: stringotpCode, const setOtpCode: React.Dispatch<React.SetStateAction<string>>setOtpCode] = useState<string>(initialState: string | (() => string)): [string, React.Dispatch<React.SetStateAction<string>>] (+1 overload)Returns a stateful value, and a function to update it.
useState("");
const const handleUserVerifyOtp: () => voidhandleUserVerifyOtp = () => {
try {
const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => voidauthenticate({
otpCode: stringotpCode,
type: "otp"type: "otp",
});
// OTP verified. User is authenticated.
} catch (function (local var) e: unknowne) {
const Alert: AlertStaticAlert.AlertStatic.alert: (title: string, message?: string, buttons?: AlertButton[], options?: AlertOptions) => voidalert("Error verifying OTP Code. Check logs for more details.");
var console: ConsoleThe console
module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream. * A global console
instance configured to write to process.stdout
and process.stderr
. The global console
can be used without importing the node:console
module.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O
for more information.
Example using the global console
:
const name = 'Will Robinson'; console.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ```
Example using the `Console` class:
```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err);
myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson'; myConsole.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
console.Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)log("Error verifying OTP CODE: ", function (local var) e: unknowne);
}
};
return (
<class ViewView>
<class ViewView>
<class TextText>Enter Your OTP Code</class TextText>
<class ViewView>
<class TextInputTextInput
value?: string | undefinedThe value to show for the text input. TextInput is a controlled component, which means the native value will be forced to match this value prop if provided. For most uses this works great, but in some cases this may cause flickering
one common cause is preventing edits by keeping value the same. In addition to simply setting the same value, either set editable=false, or set/update maxLength to prevent unwanted edits without flicker.
value={const otpCode: stringotpCode}
onChangeText?: ((text: string) => void) | undefinedCallback that is called when the text input's text changes. Changed text is passed as an argument to the callback handler.
onChangeText={const setOtpCode: React.Dispatch<React.SetStateAction<string>>setOtpCode}
placeholder?: string | undefinedThe string that will be rendered before text input has been entered
placeholder="123456"
/>
<const Pressable: React.ForwardRefExoticComponent<PressableProps & React.RefAttributes<View>>Pressable PressableProps.onPress?: ((event: GestureResponderEvent) => void) | null | undefinedCalled when a single tap gesture is detected.
onPress={const handleUserVerifyOtp: () => voidhandleUserVerifyOtp}>
{({ pressed: booleanpressed }) => (
<class ViewView
style?: StyleProp<ViewStyle>style={[
{
ViewStyle.opacity?: AnimatableNumericValue | undefinedopacity: pressed: booleanpressed ? 0.5 : 1,
TransformsStyle.transform?: string | readonly (({
perspective: AnimatableNumericValue;
} & {
rotate?: undefined;
rotateX?: undefined;
rotateY?: undefined;
rotateZ?: undefined;
scale?: undefined;
scaleX?: undefined;
... 5 more ...;
matrix?: undefined;
}) | ... 11 more ... | ({
...;
} & {
...;
}))[] | undefinedtransform: [
{
scale: AnimatableNumericValuescale: pressed: booleanpressed ? 0.98 : 1,
},
],
},
]}
>
<class TextText>Submit OTP</class TextText>
</class ViewView>
)}
</const Pressable: React.ForwardRefExoticComponent<PressableProps & React.RefAttributes<View>>Pressable>
</class ViewView>
</class ViewView>
</class ViewView>
);
}
Here’s an example of a Sign In component using OTP. Feel free to embed this into your application to give it a try!
import React, { function useCallback<T extends Function>(callback: T, deps: React.DependencyList): TuseCallback
will return a memoized version of the callback that only changes if one of the inputs
has changed.
useCallback, function useState<S>(initialState: S | (() => S)): [S, React.Dispatch<React.SetStateAction<S>>] (+1 overload)Returns a stateful value, and a function to update it.
useState } from "react";
import { class ViewView, class TextText, class TextInputTextInput, class ButtonButton } from "react-native";
import { function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate, const useUser: () => UseUserResultA React hook that returns the current user information, either from an External Owned Account (EOA) or from the client store. It uses the Alchemy account context and synchronizes with external store updates. The best way to check if user is logged in for both smart account contract users and EOA.
If using smart contract account, returns address of the signer. If only using smart account contracts then you can use useSignerStatus or useAccount to see if the account is defined.
useUser } from "@account-kit/react-native";
import { import OtpPopUpOtpPopUp } from "./otp-popup";
export const const SignInWithOtp: () => JSX.ElementSignInWithOtp = () => {
const [const email: stringemail, const setEmail: React.Dispatch<React.SetStateAction<string>>setEmail] = useState<string>(initialState: string | (() => string)): [string, React.Dispatch<React.SetStateAction<string>>] (+1 overload)Returns a stateful value, and a function to update it.
useState<string>("");
const [const showOtp: booleanshowOtp, const setShowOtp: React.Dispatch<React.SetStateAction<boolean>>setShowOtp] = useState<boolean>(initialState: boolean | (() => boolean)): [boolean, React.Dispatch<React.SetStateAction<boolean>>] (+1 overload)Returns a stateful value, and a function to update it.
useState<boolean>(false);
const [const loading: booleanloading, const setLoading: React.Dispatch<React.SetStateAction<boolean>>setLoading] = useState<boolean>(initialState: boolean | (() => boolean)): [boolean, React.Dispatch<React.SetStateAction<boolean>>] (+1 overload)Returns a stateful value, and a function to update it.
useState<boolean>(false);
const { const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate } = function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate();
const { const user: anyuser } = function useUser(): UseUserResultA React hook that returns the current user information, either from an External Owned Account (EOA) or from the client store. It uses the Alchemy account context and synchronizes with external store updates. The best way to check if user is logged in for both smart account contract users and EOA.
If using smart contract account, returns address of the signer. If only using smart account contracts then you can use useSignerStatus or useAccount to see if the account is defined.
useUser();
// Make an authentication request to a user's email
const const performAuthRequest: (email: string) => voidperformAuthRequest = useCallback<(email: string) => void>(callback: (email: string) => void, deps: React.DependencyList): (email: string) => voiduseCallback
will return a memoized version of the callback that only changes if one of the inputs
has changed.
useCallback(
(email: stringemail: string) => {
try {
const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => voidauthenticate({
email: stringemail,
type: "email"type: "email",
emailMode?: "otp" | "magicLink" | undefinedemailMode: "otp",
});
const setLoading: (value: React.SetStateAction<boolean>) => voidsetLoading(true);
const setShowOtp: (value: React.SetStateAction<boolean>) => voidsetShowOtp(true);
} catch (function (local var) e: unknowne) {
anyAlert.anyalert("Error sending OTP Code. Check logs for more details.");
var console: ConsoleThe console
module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream. * A global console
instance configured to write to process.stdout
and process.stderr
. The global console
can be used without importing the node:console
module.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O
for more information.
Example using the global console
:
const name = 'Will Robinson'; console.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ```
Example using the `Console` class:
```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err);
myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson'; myConsole.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
console.Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)Prints to stdout
with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3)
(the arguments are all passed to util.format()
).
js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout
See util.format()
for more information.
log("Error seding OTP CODE: ", function (local var) e: unknowne);
}
},
[const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate],
);
const const completeAuth: () => voidcompleteAuth = useCallback<() => void>(callback: () => void, deps: React.DependencyList): () => voiduseCallback
will return a memoized version of the callback that only changes if one of the inputs
has changed.
useCallback(() => {
const setLoading: (value: React.SetStateAction<boolean>) => voidsetLoading(false);
const setShowOtp: (value: React.SetStateAction<boolean>) => voidsetShowOtp(false);
}, []);
return (
<class ViewView>
{const user: anyuser && (
<>
<class TextText>User Authenticated As: {const user: anyuser.anyemail}</class TextText>
<class TextText>{const user: anyuser.anyaddress}</class TextText>
</>
)}
<class TextText style?: StyleProp<TextStyle>style={{ TextStyle.fontSize?: number | undefinedfontSize: 16 }}>Enter Email</class TextText>
<class TextInputTextInput
value?: string | undefinedThe value to show for the text input. TextInput is a controlled component, which means the native value will be forced to match this value prop if provided. For most uses this works great, but in some cases this may cause flickering
one common cause is preventing edits by keeping value the same. In addition to simply setting the same value, either set editable=false, or set/update maxLength to prevent unwanted edits without flicker.
value={const email: stringemail}
style?: StyleProp<TextStyle>Styles
style={{ TextStyle.fontSize?: number | undefinedfontSize: 20 }}
onChangeText?: ((text: string) => void) | undefinedCallback that is called when the text input's text changes. Changed text is passed as an argument to the callback handler.
onChangeText={const setEmail: React.Dispatch<React.SetStateAction<string>>setEmail}
placeholder?: string | undefinedThe string that will be rendered before text input has been entered
placeholder="Enter Email"
autoCapitalize?: "none" | "sentences" | "words" | "characters" | undefinedCan tell TextInput to automatically capitalize certain characters. characters: all characters, words: first letter of each word sentences: first letter of each sentence (default) none: don't auto capitalize anything
autoCapitalize="none"
/>
<class ButtonButton
title: stringText to display inside the button. On Android the given title will be converted to the uppercased form.
title={const loading: booleanloading ? "Loading" : "Sign In"}
disabled?: boolean | undefinedIf true, disable all interactions for this component.
disabled={const loading: booleanloading}
onPress?: ((event: GestureResponderEvent) => void) | undefinedCalled when the touch is released, but not if cancelled (e.g. by a scroll that steals the responder lock).
onPress={() => const performAuthRequest: (email: string) => voidperformAuthRequest(const email: stringemail)}
/>
<import OtpPopUpOtpPopUp
show: booleanshow={const showOtp: booleanshowOtp}
completeAuth: () => voidcompleteAuth={const completeAuth: () => voidcompleteAuth}
close: () => voidclose={() => {
const setShowOtp: (value: React.SetStateAction<boolean>) => voidsetShowOtp(false);
const setLoading: (value: React.SetStateAction<boolean>) => voidsetLoading(false);
}}
/>
</class ViewView>
);
};
import React, { function useCallback<T extends Function>(callback: T, deps: React.DependencyList): TuseCallback
will return a memoized version of the callback that only changes if one of the inputs
has changed.
useCallback, function useState<S>(initialState: S | (() => S)): [S, React.Dispatch<React.SetStateAction<S>>] (+1 overload)Returns a stateful value, and a function to update it.
useState } from "react";
import {
class ModalModal,
class TextText,
class TextInputTextInput,
class ButtonButton,
class SafeAreaViewSafeAreaView,
type Alert = AlertStatic
const Alert: AlertStaticAlert,
} from "react-native";
import { function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate } from "@account-kit/react-native";
export const const OtpPopUp: ({ show, completeAuth, close, }: {
show: boolean;
completeAuth: () => void;
close: () => void;
}) => JSX.ElementOtpPopUp = ({
show: booleanshow,
completeAuth: () => voidcompleteAuth,
close: () => voidclose,
}: {
show: booleanshow: boolean;
completeAuth: () => voidcompleteAuth: () => void;
close: () => voidclose: () => void;
}) => {
const { const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate } = function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate();
const [const otpCode: stringotpCode, const setOtpCode: React.Dispatch<React.SetStateAction<string>>setOtpCode] = useState<string>(initialState: string | (() => string)): [string, React.Dispatch<React.SetStateAction<string>>] (+1 overload)Returns a stateful value, and a function to update it.
useState<string>("");
const [const loading: booleanloading, const setLoading: React.Dispatch<React.SetStateAction<boolean>>setLoading] = useState<boolean>(initialState: boolean | (() => boolean)): [boolean, React.Dispatch<React.SetStateAction<boolean>>] (+1 overload)Returns a stateful value, and a function to update it.
useState<boolean>(false);
// Authenticate a user using a bundle returned from a deep link
const const handleUserOtp: (otpCode: string) => voidhandleUserOtp = useCallback<(otpCode: string) => void>(callback: (otpCode: string) => void, deps: React.DependencyList): (otpCode: string) => voiduseCallback
will return a memoized version of the callback that only changes if one of the inputs
has changed.
useCallback(
(otpCode: stringotpCode: string) => {
try {
const setLoading: (value: React.SetStateAction<boolean>) => voidsetLoading(true);
const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => voidauthenticate({ otpCode: stringotpCode, type: "otp"type: "otp" }); //<-- Pass the user's OTP code to the authenticate method using `otp` as the type value
completeAuth: () => voidcompleteAuth();
} catch (function (local var) e: unknowne) {
const Alert: AlertStaticAlert.AlertStatic.alert: (title: string, message?: string, buttons?: AlertButton[], options?: AlertOptions) => voidalert("Error verifying OTP Code. Check logs for more details.");
var console: ConsoleThe console
module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream. * A global console
instance configured to write to process.stdout
and process.stderr
. The global console
can be used without importing the node:console
module.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O
for more information.
Example using the global console
:
const name = 'Will Robinson'; console.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ```
Example using the `Console` class:
```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err);
myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson'; myConsole.warn(`Danger $name! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
console.Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)Prints to stdout
with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3)
(the arguments are all passed to util.format()
).
js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout
See util.format()
for more information.
log("Error verifying OTP CODE: ", function (local var) e: unknowne);
}
},
[const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate],
);
return (
<class ModalModal visible?: boolean | undefinedThe visible
prop determines whether your modal is visible.
visible={show: booleanshow} style?: StyleProp<ViewStyle>style={{ FlexStyle.paddingTop?: DimensionValue | undefinedpaddingTop: 200 }}>
<class SafeAreaViewSafeAreaView style?: StyleProp<ViewStyle>style={{ FlexStyle.margin?: DimensionValue | undefinedmargin: 20 }}>
<class TextText style?: StyleProp<TextStyle>style={{ TextStyle.fontSize?: number | undefinedfontSize: 16 }}>Enter OTP</class TextText>
<class TextInputTextInput
style?: StyleProp<TextStyle>Styles
style={{ TextStyle.fontSize?: number | undefinedfontSize: 20 }}
value?: string | undefinedThe value to show for the text input. TextInput is a controlled component, which means the native value will be forced to match this value prop if provided. For most uses this works great, but in some cases this may cause flickering
one common cause is preventing edits by keeping value the same. In addition to simply setting the same value, either set editable=false, or set/update maxLength to prevent unwanted edits without flicker.
value={const otpCode: stringotpCode}
onChangeText?: ((text: string) => void) | undefinedCallback that is called when the text input's text changes. Changed text is passed as an argument to the callback handler.
onChangeText={const setOtpCode: React.Dispatch<React.SetStateAction<string>>setOtpCode}
placeholder?: string | undefinedThe string that will be rendered before text input has been entered
placeholder="Enter OTP"
/>
<class ButtonButton
title: stringText to display inside the button. On Android the given title will be converted to the uppercased form.
title={const loading: booleanloading ? "Loading" : "Submit OTP"}
disabled?: boolean | undefinedIf true, disable all interactions for this component.
disabled={const loading: booleanloading}
onPress?: ((event: GestureResponderEvent) => void) | undefinedCalled when the touch is released, but not if cancelled (e.g. by a scroll that steals the responder lock).
onPress={() => const handleUserOtp: (otpCode: string) => voidhandleUserOtp(const otpCode: stringotpCode)}
/>
<class ButtonButton
title: stringText to display inside the button. On Android the given title will be converted to the uppercased form.
title="Close"
onPress?: ((event: GestureResponderEvent) => void) | undefinedCalled when the touch is released, but not if cancelled (e.g. by a scroll that steals the responder lock).
onPress={() => {
const setLoading: (value: React.SetStateAction<boolean>) => voidsetLoading(false);
close: () => voidclose();
}}
/>
</class SafeAreaViewSafeAreaView>
</class ModalModal>
);
};