Answer a question

I'm using the latest Redux toolkit and I'm trying to throttle keydown and keyup actions, but I cannot understand why it's not working... I have a feeling it has something to do with dispatch, but I tried throttling the dispatch with no luck either.

Is this not possible?

  // this does NOT get throttled
  const handleOnKeyDown = (e) => {
    e.persist();
    if (e.key === 'ArrowUp') {
      dispatch(setSelectedPage(pageAbove)); // not throttled
    } else if (e.key === 'ArrowDown') {
      dispatch(setSelectedPage(pageBelow)); // not throttled
    }
  };

  // this DOES get throttled
  const handleOnKeyDown = (e) => {
    e.persist();
    console.log('test');
  };

  const throttledOnKeyDown = _.throttle(handleOnKeyDown, 1000);

I also tried the following but this doesn't work either:

  const throttleSetSelectedPage = _.throttle((param) => dispatch(setSelectedPage(param)), 1000);

  const handleOnKeyDown = (e) => {
    e.persist();
    if (e.key === 'ArrowUp') {
      throttleSetSelectedPage(pageAbove);
    } else if (e.key === 'ArrowDown') {
      throttleSetSelectedPage(pageBelow);
    }
  };

Answers

You need to wrap the _.throttle() in a useCallback() hook.

In react functional components, the function body is called on every render so the line const throttledOnKeyDown = _.throttle(handleOnKeyDown, 1000); gets called every render and creates a new instance of the _.throttle() function so it can never reach its settling time. useCallback memoizes the function so that you get the same instance from one render to the next.

See this blog post about using _.debounce() in react. The same concept applies to throttle: https://nodeployfriday.com/posts/react-debounce/

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐