The SignUp UI does not render few fields sometimes
Before creating a new issue, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
- [X] I have tried disabling all browser extensions or using a different browser
- [X] I have tried deleting the node_modules folder and reinstalling my dependencies
- [X] 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?
Vite
What browsers are you seeing the problem on?
Chrome
Which region are you seeing the problem in?
No response
Please describe your bug.
The SignUp UI does not render few fields sometimes. It happens so randomly, that I cannot even tell you how to reproduce. I tried different browsers, different steps etc. I wish I could tell you more, but I can just provide the code I am using and the Screenshots, maybe it is something, you faced as well.
Here is the screenshot, without fields (happens very randomly):
After F5 Browser refresh, everything looks just fine:
What's the expected behaviour?
The defined SignUp fields are ALWAYS rendered
Help us reproduce the bug!
It happens so randomly, that I cannot even tell you how to reproduce. I tried different browsers, different steps etc. I wish I could tell you more, but I can just provide the code I am using and the Screenshots, maybe it is something, you faced as well.
Code Snippet
const cognitoFormFields = {
signUp: {
given_name: {
label: t('auth.screen.signup.firstname.label'),
placeholder: t('auth.screen.signup.firstname.placeholder'),
isRequired: true,
defaultValue: searchParams.get('firstname') || '',
order: 2,
},
family_name: {
label: t('auth.screen.signup.lastname.label'),
placeholder: t('auth.screen.signup.lastname.placeholder'),
isRequired: true,
defaultValue: searchParams.get('lastname') || '',
order: 3,
},
username: {
label: t('auth.screen.signup.email.label'),
placeholder: t('auth.screen.signup.email.placeholder'),
isRequired: true,
defaultValue: searchParams.get('email') || '',
order: 4,
},
password: {
label: t('auth.screen.signup.password.label'),
placeholder: t('auth.screen.signup.password.placeholder'),
isRequired: true,
order: 5,
}
}
<Authenticator
className="pt-20"
formFields={cognitoFormFields}
signUpAttributes={['family_name', 'given_name']}
components={cognitoComponents()}
services={cognitoServices}
initialState={value.authState} // login, signUp
>
{children}
</Authenticator>
Console log output
nothing special here
Additional information and screenshots
No response
@leantrace this is definitely a strange issue. Without a consistent way to reproduce it may be difficult to find the root cause, but based on the information you provided we'll attempt a reproduction and get back to you.
@leantrace could you provide your package.json?
Hi @esauerbo thank you to take a look into it. I hope I find a way to reproduce it. I am even suspecting, that it might have to do with some Browser plugins/blockers.
Sure I can provide my package.json package.json
@leantrace I removed attributes where the implementation wasn't shown, like components and services, and was not able to reproduce this behavior. Can you try using the Authenticator component with just formFields and see if you get the same issue? It's possible that custom logic is affecting how the component renders.
If the issue persists, please provide a minimum reproducible example that includes everything we would need to reproduce this behavior. Even though it might not be consistently reproducible, it would be helpful to isolate the simplest version of your code that still results in this error.
@esauerbo I will reduce it to the minimum and try to reproduce. I know it is hard for you to reproduce without any given steps from my side. I have the same problem. I hope I can figure it out, what causes it and provide here more information. Thank you for taking it seriously. Appreciate!
@leantrace I would look into what you're doing inside of the cognitoComponents() function, as that looks like it firing on every render. What are you doing in cognitoComponents?
Can you please provide a more complete code sample?
@reesscot , @esauerbo Ultimately I found out what was going wrong or weird!
I our application we use the Authentificator only if the user clicks on login or signUp, because we have a public page, it looks like this:
<div
style={{
'--amplify-components-button-primary-background-color': primary,
'--amplify-components-button-primary-hover-background-color': secondary,
} as React.CSSProperties}
>
<CognitoAuthenticatorContext.Provider value={value}>
{ value.authState === 'signOut' ? <div>{children}</div>
: (
<Authenticator
className="pt-20"
formFields={cognitoFormFields}
components={cognitoComponents(landingPage)}
services={cognitoServices}
initialState={value.authState} // login, signUp
>
{children}
</Authenticator>
)}
</CognitoAuthenticatorContext.Provider>
</div>
The CognitoAuthenticatorContext.Provider manages the state of the page
export type AuthState = 'signOut' | 'signIn' | 'signUp'
When we change our internal state to 'signUp', the login Authenticator page will be rendered and the Authenticator route-state will be 'signUp'. If I now switch the tab to signIn the Authenticator route-state will be signIn, BUT our internal context state will remain 'signUp'. Now if I click Browser back our internal state changes to 'signOut' and the Authenticator is not rendered anymore, if you look ant our implementation above. All good so far!
The Authenticator route state is now still 'signIn'. So if I click on our Button 'signUp', the 'signIn' page will pop-up. If I switch to 'signUp' tab now, the <Authenticator.SignUp.FormFields /> sometimes remain the default fields without our customFormFields.
I could solve the issue (or at least I did not see it anymore since then) by setting the route state of the Authenticator accordingly, when switching our internal state, see setAuthState method:
const CognitoAuthenticator = (props: CognitoAuthenticatorProps) => {
const [authState, setAuthnState] = useState<AuthState>('signOut')
const { toSignIn, toSignUp } = useAuthenticator((context) => [context.route])
const setAuthState = (state: AuthState) => {
setAuthnState(state)
if (state === 'signIn') {
toSignIn()
} else if (state === 'signUp') {
toSignUp()
}
}
const value = useMemo(() => ({ authState, setAuthState }), [authState, setAuthState])
I hope that helps
Hey @leantrace glad you were able to find a solution. Is there anything else you need help with?
Closing this out as you found a solution. Please open a new issue if you have further questions!