Link element fires up onSubmit form event when rerenders.
Not firing up the onSubmit event
import React, { useState } from 'react'
import {
Button,
TextField,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Link
} from '@material-ui/core'
import { useSnackbar } from 'notistack'
import { AuthActions } from '../../actions'
import { connect, ConnectedProps } from 'react-redux'
import { unwrapResult } from '@reduxjs/toolkit'
import { useForm } from 'react-hook-form'
const mapDispatchToProps = {
login: AuthActions.login,
register: AuthActions.register
}
const connector = connect(null, mapDispatchToProps)
type AuthDialogProps = ConnectedProps<typeof connector> & {
open: boolean
onClose: () => void
}
type FormData = {
login: string
email: string
password: string
}
const emailRegExp = /^(?:(?:[^<>()\[\]\\.,;:\s@"]+(?:\.[^<>()\[\]\\.,;:\s@"]+)*)|(?:".+"))@(?:(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(?:(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
const AuthDialog = ({
open,
onClose,
login: loginAction,
register: registerAction
}: AuthDialogProps) => {
const [registered, setRegistered] = useState(false)
const [error, setError] = useState('')
const { enqueueSnackbar } = useSnackbar()
const { register, handleSubmit, errors, clearError } = useForm<FormData>()
return (
<Dialog open={open} onClose={onClose} aria-labelledby="form-dialog-title">
<form
onSubmit={handleSubmit(async ({ login, email, password }, e) => {
if (registered) {
try {
const action = await loginAction({ login, password })
unwrapResult(action)
enqueueSnackbar('Logged in successfully')
onClose()
} catch (e) {
setError(e.message)
}
} else {
const action = await registerAction({ email, login, password })
try {
unwrapResult(action)
enqueueSnackbar(
'Registered successfully, confirm your account in a message we sent to the email'
)
onClose()
} catch (e) {
setError(e.message)
}
}
})}
>
<DialogTitle id="form-dialog-title">{registered ? 'Log in' : 'Register'}</DialogTitle>
<DialogContent>
{!registered && (
<TextField
autoFocus
margin="dense"
name="email"
label="Email Address"
onChange={() => setError('')}
type="email"
error={!!(errors.email || error)}
helperText={error ? error : errors.email && 'Wrong email format'}
inputRef={register({ required: true, pattern: emailRegExp })}
fullWidth
/>
)}
<TextField
autoFocus
margin="dense"
name="login"
label="Login"
type="login"
onChange={() => setError('')}
error={!!(errors.login || error)}
helperText={error ? error : 'Login needs to have 3-20 symbols'}
inputRef={register({ required: true, minLength: 3, maxLength: 20 })}
fullWidth
/>
<TextField
autoFocus
margin="dense"
name="password"
label="Password"
type="password"
error={!!errors.password}
helperText="Password needs to have 6-20 symbols"
inputRef={register({ required: true, minLength: 6, maxLength: 20 })}
fullWidth
/>
<Link
component="button"
variant="body2"
onClick={() => {
clearError('login')
clearError('password')
clearError('email')
setRegistered(!registered)
setError('')
}}
>
{registered ? 'Not registered? Register now.' : 'Already registered? Login now.'}
</Link>
</DialogContent>
<DialogActions>
<Button onClick={onClose} color="primary">
Cancel
</Button>
<Button color="primary" type="submit">
{registered ? 'Login' : 'Register'}
</Button>
</DialogActions>
</form>
</Dialog>
)
}
export default connector(AuthDialog)
I'm trying to achieve seamless register-login form transition, but everytime I switch from register back to login, form fires up onSubmit event, when I removed component out of Link, everything worked fine
| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.?.? |
| React | v16.9.7 |
| Browser | x |
| TypeScript | v3.7.5 |
| etc. | |
Thanks for the issue.
Could you create a codesandbox using https://material-ui.com/r/issue-template and explain the steps that reproduces this issue? It's not clear if this is an issue with the other libraries, Material-UI or the integration.
Link element fires up onSubmit form event when rerenders.
How would you know that from the code? Link doesn't have an onSubmit handler.
How would you know that from the code? Link doesn't have an onSubmit handler.
Yeah, you're totally right, but I'm using it inside <form>, and for some reasons, when the component is button, it triggers form's onSubmit, but when it's not a button, it doesn't

Yeah we don't add a type to button in Link which defaults to submit. <Link component="button" type="button" /> would work.
But I don't think we want to overload the Link/Button choice even more. You're want a <button> so why not use a <Button>? Mixing styles with semantics can be very disorienting.
Ok, thanks for clearance!
Most helpful comment
Yeah we don't add a
typeto button in Link which defaults to submit.<Link component="button" type="button" />would work.But I don't think we want to overload the Link/Button choice even more. You're want a
<button>so why not use a<Button>? Mixing styles with semantics can be very disorienting.