Home > Back-end >  Disable button on Form Submit in React
Disable button on Form Submit in React

Time:07-09

For some reason, my Sign In button does not become disabled when the form is submitted. Is there something obviously incorrect?

It is supposed to be disabled when processing a user's sign in API request.

This is also not a result of a fast API, because even if I set the network speed to very slow, it does not become disabled at any point.

import React, { useRef, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import {
  Alert, Box, Card, TextField, Typography,
} from '@mui/material';
import LoadingButton from '@mui/lab/LoadingButton';
import { useAuth } from '../context/AuthContext';
import '../../pages/bg.css';

export default function SignInAuth() {
  const emailRef = useRef();
  const passwordRef = useRef();
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const navigate = useNavigate();
  const auth = useAuth();

  async function handleSubmit(e) {
    e.preventDefault();

    if (!emailRef.current.value) {
      return setError('Please enter an Email Address');
    }

    if (!passwordRef.current.value) {
      return setError('Please enter a password');
    }

    setLoading(true);
    setError('');

    fetch(
      `${process.env.REACT_APP_API_URL}auth/login`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({
          Email: emailRef.current.value,
          Password: passwordRef.current.value,
        }),
      },
    ).then((response) => {
      if (response.ok) {
        auth.signin(emailRef.current.value);
        return navigate('/Dashboard');
      }
      // Response must be handled in a promise.
      return response.json().then((errorText) => { throw new Error(errorText.message); });
    }).then(setLoading(false)).catch((err) => {
      setError(err.message); // This comes from the returned error promise.
      // System throws error, and then error is set for the text.
    });
    return null;
  }

  const onSubmit = (e) => {
    handleSubmit(e);
  };

  const textFieldStyle = {
    width: '300px',
  };

  return (
    <Box sx={{
      zIndex: 1,
      minWidth: '200px',
      width: '450px',
    }}
    >
      <Card sx={{ p: '20px', borderRadius: '15px' }}>
        <Typography variant="h4" sx={{ fontWeight: 600, textAlign: 'center', mb: '8px' }}>Sign In</Typography>

        <form onSubmit={(e) => onSubmit(e)}>
          <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
            {error && <Alert severity="error" sx={{ ...textFieldStyle, my: '10px' }}>{error}</Alert>}
            <TextField autoFocus margin="normal" inputRef={emailRef} type="email" id="email" label="Email" sx={textFieldStyle} />
            <TextField margin="normal" inputRef={passwordRef} type="password" id="password" label="Password" sx={textFieldStyle} />
            <LoadingButton
              sx={{ mt: '16px', mb: '4px', width: '150px' }}
              loading={loading}
              variant="contained"
              type="submit"
            >
              Sign In
            </LoadingButton>
          </Box>
        </form>
        <Typography variant="subtitle1" align="center" sx={{ mt: '10px' }}>
          <Link to="/forgot-password">Forgot Password?</Link>
        </Typography>
      </Card>
      <Box>
        <Typography variant="subtitle1" align="center" sx={{ mt: '10px' }}>
          Need an account?
          {' '}
          <Link to="/SignUp">Sign Up</Link>
        </Typography>
      </Box>
    </Box>
  );
}

CodePudding user response:

According to the documentation, you must pass in a disabled prop to the LoadingButton component. Set it to be the same as your loading state.

<LoadingButton 
  sx={{ mt: '16px', mb: '4px', width: '150px' }} 
  loading={loading} 
  disabled={loading}
  variant="contained" 
  type="submit"
>
  Sign In
</LoadingButton>
  • Related