Use React to increment a variable by a random value until it reaches a specific threshold

I am currently working on creating a simulated loading bar, similar to the one seen on YouTube videos. My goal is for it to last 1.5 seconds, which is the average time it takes for my page to load. However, I have encountered an issue with the following code:

  const [fakeLoader, setFakeLoader] = useState(0);

  const startLoader = useCallback(() => {
    if (fakeLoader > 100) return;
    requestAnimationFrame(startLoader);

    if (Math.random() < 0.05) {
      setFakeLoader((prev) => (prev += Math.random() * 3));
    }
  }, []);

  useEffect(() => {
    startLoader();
  }, [startLoader]);

The problem lies in the fact that fakeLoader always remains at 0 within the startLoader function, preventing the conditional statement from running. I attempted removing the useCallback, but found that this caused the function to constantly change, potentially leading to memory leaks or other issues.

Answer №1

There are some issues within your code, but the primary concern lies in the stale enclosure of the fakeLoader state within the useCallback hook.

To address this, one possible solution involves utilizing an interval to periodically check if a state update is required. Through a slight refactoring, a custom useInterval hook can be implemented. By moving the condition fakeLoader < 100 into the functional state update callback, it allows for correct referencing of the previous state.

const useInterval = (callback, delay) => {
  const savedCallback = React.useRef(null);

  React.useEffect(() => {
    savedCallback.current = callback;
  });

  React.useEffect(() => {
    const id = setInterval(savedCallback.current, delay);
    return () => clearInterval(id);
  }, [delay]);
};

function App() {
  const [fakeLoader, setFakeLoader] = React.useState(0);

  const startLoader = () => {
    setFakeLoader((fakeLoader) => {
      if (fakeLoader < 100 && Math.random() < 0.05) {
        return Math.min(fakeLoader + Math.random() * 3, 100);
      }
      return fakeLoader;
    });
  };

  useInterval(startLoader, 100 / 6); // 16.666ms is approx 60fps

  React.useEffect(() => {
    console.log(fakeLoader);
  }, [fakeLoader]);

  return (
    <div className="App">
      fakeLoader: {fakeLoader.toFixed(2)}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root" />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Errors are caused when attempting to install third-party JS plugins using npm within a foundation project

I am currently exploring projects involving NodeJS and npm. While experimenting with foundation CLI in Foundation 6.4, I decided to install a 3rd Party JS plugin called chart.js from Following their documentation, I ran the command: npm install chart.js ...

Include personalized headers to the 'request'

I have configured my express server to proxy my API using the following setup: // Proxy api calls app.use('/api', function (req, res) { let url = config.API_HOST + req.url req.pipe(request(url)).pipe(res) }) In this instance, confi ...

Monitor a user's activity and restrict the use of multiple windows or tabs using a combination of PHP and

I am looking to create a system that restricts visitors to view only one webpage at a time, allowing only one browser window or tab to be open. To achieve this, I have utilized a session variable named "is_viewing". When set to true, access to additional ...

What is the best way to create a list from a matrix using JavaScript?

I have an array structured as follows: const input_array= [ ["red", "green"], ["small", "medium"], ["x", "y", "z"] //... can have any number of rows added dynamically ...

Sending a JavaScript function as part of an ajax response

I'm currently working on a system where the user can submit a form through AJAX and receive a callback in response. The process involves the server processing the form data and returning both an error message and a JavaScript function that can perform ...

Discovering the proper method to reach the parent element in jQuery while within the click event

How can I use jQuery to access the parent element within a click event? $(document).ready(function () { $(".lv1 li").click(function (event) { this.parentElement.parentElement.textContent = this.textContent; $.ajax({ type: 'post&apo ...

Obtain data with matching JSON values in a REACT application

Recently, I received a JSON file that looks something like this: [ { "symbol": "A", "name": "Agilent Technologies Inc", "exchange": "NYSE", }, { "symbol": "AAC ...

Why am I receiving an error message stating "undefined is not a function" when trying

I am attempting to create a popover using the Angular UI pop over feature. I have loaded my HTML and compiled it, but when I run my program and click on the star icon (where I display the popover), I receive an error stating that 'undefined is not a f ...

Using Node.js and Less to dynamically select a stylesheet source depending on the subdomain

Currently, my tech stack consists of nodejs, express, jade, and less. I have set up routing to different subdomains (for example: college1.domain.com, college2.domain.com). Each college has its own unique stylesheet. I am looking for a way to selectively ...

Steps for generating random numbers from a set of given numbers

I am faced with a scenario where I need to generate random numbers based on a given set of numbers. For instance, if I have an array num=[23,56,12,22], I would like to obtain a random number from this array. ...

Facing problem with Angular 7 when making a GET request for non-JSON data

Currently, I am retrieving JSON data from a URL using the following method: this.http.get('http://localhost:3200/mydata').subscribe(data => { console.log(data); }); The response is in JSON format, and everything seems to be working fine. ...

Another option instead of using $index for displaying serial numbers in ng-repeat

Looking to display a serial number for each table data entry being generated through the use of ng-repeat. The current code I have is as follows: <tr ng-repeat="usageRecord in applicationUsageDataForReport"> <td style="text-align: center">&l ...

The cookie being sent from the backend API (implemented in nodeJS using express) to the frontend (developed with NextJS) is not successfully setting in the

I'm currently working on a NextJS app running on localhost:3000 and a node express API running on localhost:3030. I have encountered an issue where, after sending a request from the frontend to the backend login route, I am trying to set a cookie call ...

When the Fetch response displays a 401 Unauthenticated error, it typically indicates an issue with authentication in a React frontend

For a university assignment, I developed a Spring Boot backend that requires authorization/authentication. The API functions correctly when tested standalone through Postman requests with the correct authentication/authorization. However, when attempting t ...

The absence of a closing parentheses in the argument is causing an issue when rendering

Apologies for the basic mistake, but I could really use some assistance with this syntax error. I've spent over an hour searching for it and still haven't been able to locate the issue. It seems to be around the success function(data) section. Th ...

What could be the reason for the absence of this Javascript function in my attribute?

I have been working on an app using electron, and I have a function that successfully adds tabs to the app. The issue arises when I try to add tabs via JavaScript with the onclick attribute - they show up as expected but do not execute the code to hide and ...

JavaScript code for iframe auto resizing is not functioning properly on Firefox browser

I have implemented a script to automatically resize the height and width of an iframe based on its content. <script language="JavaScript"> function autoResize(id){ var newheight; var newwidth; if(document.getElementById){ newh ...

The specific property 'splice' cannot be found within type 'T'

As I delve into working with TypeScript, an unexpected error arises: Property 'splice' does not exist on type 'T'. type Item = { name: string, body: string, imgOne: string, imgTwo: string, }[] // Another file contains this func ...

Transforming form inputs into JSON structure

<form name = 'test' > <input type='text' name = 'login'> <input type='email' name = 'email'> </form> When I try to convert the form data using JSON.serialize($(form)).serial ...

The output of the Node.js crypto.pbkdf2 function may not match the result obtained from CryptoJS.PBKDF

Currently, I am utilizing PBKDF2 on both the frontend with CryptoJS and the backend with Node.js. Despite using the identical salt, algorithm, number of iterations, and password, the derived keys are turning out to be different. Below is the code snippet ...