Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Displaying a loading spinner for a minimum duration

Tags:

reactjs

I have 2 questions ...

  1. During Registration submission process, I need to display a Loading component until the response is received from the server.

The loading component is not rendering:

const Register: FC<RouteComponentProps> = () => {

  const [loading, setLoading] = useState<boolean>(false)
  const [success, setSuccess] = useState<boolean>(false)
...

const onSubmit = async(values: Values) => {

  setLoading(true)
  try {
    const response = await register({
      variables: { data: { firstName: values.first_name, lastName: values.last_name, email: values.user_email, password: values.password } }
    })
    setLoading(false)
    if (response && response.data && response.data.register) {
      setSuccess(true)
    }
  } catch (error) {

     setLoading(false)
     ...

  }
}

return (
   ...
   { loading && <Loading/> }
)

Where am I wrong, kindly let me know.

  1. Sometimes you will find that some web requests are relatively fast (< 0.5 second). In this case, the spinner will become a flicker in a web page and users don’t have enough time to understand what is happening. In order to avoid drastic web page DOM change and to reduce users’ confusion, it would be better to display the spinner for a minimum amount of time (eg, 1 second) no matter how much time it takes for loading data. How can I achieve this?

Thank you!

like image 727
cool Avatar asked Oct 26 '25 03:10

cool


2 Answers

You dont need to show loading to min 1 second since loading icon is already shown when fetching data and in real life it will be more than 1 sec.

if u want to set min 1 sec anyways

  try {
    const response = await register({
      variables: { data: { firstName: values.first_name, lastName: values.last_name, email: values.user_email, password: values.password } }
    })
//change here
 setTimeout(() => setLoading(false), 1000);
like image 131
Sushilzzz Avatar answered Oct 28 '25 17:10

Sushilzzz


you can use with Promise.all. define your fetch and define delay with promise, and you should wait when the fetch and minimum delay will finish. in general its will be like that:

function delayPromise(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
const requestPromise= fetch(....);
const res = await Promise.all([requestPromise, delayPromise(1000)]);

and in your code I think you need change to:

const registerPromise = register({
      variables: { data: { firstName: values.first_name, lastName: values.last_name, email: values.user_email, password: values.password } }
    });
const res = await Promise.all([registerPromise, delayPromise(1000)]); // your register response found in res[0]
like image 24
cohen Avatar answered Oct 28 '25 18:10

cohen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!