Open
Description
Before creating a new issue, please confirm:
- I have searched for duplicate or closed issues and discussions.
- I have tried disabling all browser extensions or using a different browser
- I have tried deleting the node_modules folder and reinstalling my dependencies
- I have read the guide for submitting bug reports.
On which framework/platform are you having an issue?
React
Which UI component?
Authenticator
How is your app built?
Create React App
What browsers are you seeing the problem on?
Firefox
Which region are you seeing the problem in?
NA
Please describe your bug.
I have successfully created an Authenticator component that supports both OTP and Username / PW, however to switch between the modes requires a full page reload. I have a boolean prop otp
that controls the visibility of the password input box. However when I call setOtp
the component does not re render; unless I do a full page reload.
Unsuccessful attempts to fix it:
- Tried to use the
key
prop - useMemo
- Separated out various parts as components
Temporary solution:
- Store the OTP value in local storage and reload the page each time the selection changes...
- Causing the entire page to flash
What's the expected behaviour?
It re renders the Authenticator component when props change.
Help us reproduce the bug!
I attached the failing code; fundamentally I am trying to avoid a full page reload when changing the otp status.
Code Snippet
import { Authenticator, Button, useAuthenticator } from "@aws-amplify/ui-react";
import { signIn, SignInInput, signUp, SignUpInput } from "aws-amplify/auth";
import { useEffect, useState } from "react";
export function LoginWindow() {
// const [otp, setOtp] = useState(false); // This useState change should render the component
const [otp, setOtp] = useState(() => {
const savedOtp = localStorage.getItem("otp");
return savedOtp === "true";
});
useEffect(() => {
localStorage.setItem("otp", otp.toString());
}, [otp]);
return (
<Authenticator
variation="modal"
initialState={"signIn"}
components={{
SignIn: {
Footer() {
const { toForgotPassword } = useAuthenticator();
return (
<>
<Button
variation="link"
size="small"
onClick={() => {
setOtp(!otp);
window.location.reload(); //Why do we need to reload the page?
}}
>
{otp ? "Sign with Password" : "Sign without Password"}
</Button>
<Button
variation="link"
size="small"
onClick={toForgotPassword}
>
Forgot Password
</Button>
</>
);
},
},
}}
loginMechanisms={["email"]}
signUpAttributes={["family_name", "given_name"]}
formFields={{
signIn: {
username: {
placeholder: "Enter Your Email Here",
isRequired: true,
label: "Email",
},
password: {
type: otp ? "hidden" : "password",
label: "Password",
labelHidden: otp,
placeholder: "Enter Your Password Here",
isRequired: !otp,
},
},
signUp: {
given_name: {
order: 1,
placeholder: "Enter Your First Name",
isRequired: true,
label: "First Name",
},
family_name: {
order: 2,
placeholder: "Enter Your Last Name",
isRequired: true,
label: "Last Name",
},
email: {
order: 3,
placeholder: "Enter Your Email",
isRequired: true,
label: "Email",
},
password: {
type: "hidden",
label: "Password",
labelHidden: true,
},
confirm_password: {
type: "hidden",
label: "Confirm Password",
labelHidden: true,
},
},
}}
services={{
async handleSignIn(input: SignInInput) {
const { username, password } = input;
return signIn({
username: username,
password: password,
options: {
authFlowType: otp ? "USER_AUTH" : "USER_PASSWORD_AUTH",
preferredChallenge: "EMAIL_OTP",
},
});
},
async handleSignUp(input: SignUpInput) {
return signUp({
username: input.username,
password: input.password,
options: {
...input.options,
autoSignIn: {
authFlowType: "USER_AUTH",
preferredChallenge: "EMAIL_OTP",
},
userAttributes: {
...input.options?.userAttributes,
email: input.username,
},
},
});
},
}}
/>
);
}
Console log output
No response
Additional information and screenshots
No response