Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

229
Views
How to show loader when there is blocking code in onClick handler?

I have a simple react component. The component has a handler that runs when the button is clicked. There is some blocking code in the handler. My task is: when I click the button the loader appears. After that, the blocking code do some heavy operations and after that, the loader disappears:

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [wait, setWait] = useState(true);

  const onClickHandler = () => {
    setWait(true);

    // Blocking code

    setWait(false);
  };

  return (
    <div className="App">
      <button onClick={onClickHandler}>Click</button>
      {wait && <div>Loading...</div>}
    </div>
  );
}

This code is artificial and I know that it is better not to do this - to block the thread. I know that batching works here. But still, I would like to know how I can show the loader in this situation. And in general, is such a situation possible in production, or is it a bad practice?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Blocking the code means that any other operation in your page will have to wait until the first one finished. If you don't care of this happening (maybe this loader covers the entire screen or you don't want the user to do anything else until the operation is done) then that's okay.

Now, maybe you want to perform this opeation while the user interacts with the page, in that case you should make use of Promises' asynchronous behavior, by using the then/catch/finally syntax. You will also need useRef so you can have access to the component's current state in the callbacks.

import { useState, useRef } from "react";
import "./styles.css";

export default function App() {

  // your big operation should return a Promise
  const bigOperation = () => {
    return new Promise((resolve, reject) => {
      resolve("Heeeey");
    })
  }

  // added "_" to the set function so it won't be confused
  // with our function to update the reference
  const [wait, _setWait] = useState(true);

  // create reference for the wait state
  const waitRef = useRef(wait);

  // function to update reference and state (mimics real one _setWait)
  const setWait = (newValue) => {
    waitRef.current = newValue;
    _setWait(newValue);
  }

  const onClickHandler = () => {
    setWait(true);

    // this executes asyncronously
    bigOperation().then(() => {
      setWait(false);
    });
  };

  return (
    <div className="App">
      <button onClick={onClickHandler}>Click</button>
      {wait && <div>Loading...</div>}
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza Report

0

There are two ways to do this

  1. Execute your blocking code later, let the loading indicator show first.

new Promise or setTimeout will do.

export default function App() {
  const [wait, setWait] = useState(true);

  const onClickHandler = () => {
    setWait(true);

    new Promise((resolve) => {
      // Blocking code
      setWait(false);
      resolve()
    });
  };

  return (
    <div className="App">
      <button onClick={onClickHandler}>Click</button>
      {wait && <div>Loading...</div>}
    </div>
  );
}
  1. Throw your Blocking code to Web Worker.

You can use custom hooks like useWorker to achieve this conveniently

useWorker: https://github.com/alewin/useWorker

about 4 years ago · Juan Pablo Isaza Report

0

I'd move the condition outside of the main return statement.

if (wait) return <div>Loading...</div>;

return (
  <div className="App">
    <button onClick={onClickHandler}>Click</button>
  </div>
);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!