daCoda
daCoda

Reputation: 3845

React / TS: Throttle function but also set state

I have a React functional component. There's an input field with the value that is set using useState. I have a simple standard function throttle(callback: Function, delay = 1000)

Requirements:

  1. Set search term (state) via onChange event handler.
  2. Throttle the callback (search()) function call.

I can do one the other, but not both. while banging my head against the wall.

Link to Code Sandbox

What am I doing wrong?

Thank you.

(FYI, I am not interested in debouncing.)

Upvotes: 0

Views: 1071

Answers (1)

mahieyin-rahmun
mahieyin-rahmun

Reputation: 1657

Using useRef to store the value of shouldWait should be the way to go. Additionally, useCallback can be used on the throttle function to memoize it.

import React, { ChangeEvent, useState, useMemo, useRef, useCallback } from "react";

/*
Requirements:
1. Set search term (state), 
2. Throttle the callback (search()) function call.

There are two functions that should be interesting, both onChange handlers: 
 * handleOnChange (Does not satisfy Requirement 2)
 * throttledOnChangeHandler (Does not satisfy Requirement 1)
*/
export const Searchbox: React.FC = () => {
  const [searchTerm, setSearchTerm] = useState("");
  const shouldWait = useRef<boolean>(false);

  const throttle = useCallback((callback: Function, delay = 1000, ...args: any[]) => {
      if (shouldWait.current) return;

      callback(...args);
      shouldWait.current = true;

      setTimeout(() => {
        shouldWait.current = false;
      }, delay);
  }, []);

  function search() {
    console.log(new Date().getSeconds())
    console.log("Searching term:", searchTerm);
  }

  const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
    throttle(search);
    setSearchTerm(e.target.value);
  };

  return (
    <div>
      <h1>Search!</h1>
      <input
        type="text"
        placeholder="Blah!"
        value={searchTerm}
        onChange={handleOnChange}
      />
    </div>
  );
};

Upvotes: 2

Related Questions