Home > other >  lodash debounce render does not work, accumulates and then is called many times
lodash debounce render does not work, accumulates and then is called many times

Time:09-01

Now the renderer works in this way, with each input of a value, it waits one second and then it is called, and it turns out that it can be called many times in a row. What needs to be done is that when the user has finished typing, the Testrender function is called only once, now it is called many times during typing

I do not understand why, when passing data between components, the function works without delay and does not maintain its purpose

https://codesandbox.io/s/blissful-meadow-o7bbqd?file=/src/components/Testrender/index.tsx:135-145

import { useState } from "react";
import Input from "./Input";
import Testrender from "./Testrender";

const Main_page = () => {
  const [count, setCount] = useState("");

  return (
    <>
      <Input count={count} setCount={setCount} />
      <Testrender count={count} />
    </>
  );
};

export default Main_page;

--

import React, { useState } from "react";

interface Props {
  count: string;
  setCount: (searchString: string) => void;
}

const Input = ({ count, setCount }: Props) => {
  return (
    <div>
      <input
        className="test-input"
        value={count}
        onChange={(e) => setCount(e.target.value)}
        placeholder="test render"
      />
    </div>
  );
};

export default Input;

--

import React, { useCallback, useEffect } from "react";
import { debounce } from "lodash";

interface Props {
  count: string;
}

const Testrender = ({ count }: Props) => {
  const request = debounce((stateValue: any) => {
    console.log("render");
  }, 1000);

  const changes = useCallback(request, [count]);

  useEffect(() => {
    changes(count);
  }, [count]);

  return <div>index</div>;
};

export default Testrender;

CodePudding user response:

Each render of a Testrender component create a new request function, each time useEffect of Testrender is triggered, it is actually calling a different request function.

In case you do multiple update to count, you will call a different debounced function each time, they will add up in parallel and you will eventually have multiple console.log instead of delaying the same debounced function.

You can use useState to init a debounced function and ensure it will not be created again

const Testrender = ({ count }: Props) => {
  const [changes] = useState(() => {
    return debounce((value) => {
      console.log("render")
    }, 1000);
  });

  useEffect(() => {
    changes(count);
  }, [count]);

  return <div>index</div>;
};
  • Related