I am new to typescript and migrating a react frontend to learn. I am currently having trouble with my login/registration component - a ternary operator is assigned to an onClick handler which dictates whether the login or signup mutation are executed. I implemented a workaround where I wrapped the mutations in functions, but it looks dirty.
Here is a barebones example, which returns a type assignment error because the values in the ternary do not share attributes with the onClick handler. I can provide a more robust, reproduceable example if necessary.
const Auth = () => {
const history = useHistory();
const [formState, setFormState] = useState({
login: true,
firstName: '',
lastName: '',
username: '',
password: '',
email: ''
});
const [loginMutation] = useMutation(LOGIN_MUTATION, {
onCompleted: (response) => {
//...
}
});
const [signupMutation] = useMutation(SIGNUP_MUTATION, {
variables: {
//...
},
onCompleted: (response) => {
// ...
}
});
return (
<>
{!formState.login && (
display extra inputs for registration form
)}
username and password fields
<button onClick={formState.login ? login : signup}>
{formstate.login ? login: signup}
</button>
</>
)
}
As you correctly guessed onClick
has signature (e:MouseEvent<HTMLButtonElement, MouseEvent>) => void
while mutation has a different signature (something along the lines of (options?: MutationFunctionOptions<T>) => Promise<Result>
). So, when you say, onClick={login}
you are essentially doing this: onClick={e => login(e)}
which is wrong.
One way to fix it is to write an inline function
<button onClick={() => formState.login ? login() : signup()}>
{formstate.login ? login: signup}
</button>