Search code examples
reactjstypescriptreact-hooksapollo-clienttsx

Assigning apollo mutations with a ternary in an onClick?


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>
    </>
)

}


Solution

  • 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>