为什么在 Material-UI 文档中使用 useMemo 进行自动完成?

Why is useMemo used in the Material-UI documentation for the autocomplete?

我特别指的是自动完成文档中的 this demo

在 google 地图示例中,有一个从 useMemo 返回的节流函数,第二个参数为空数组。但是如果数组丢失了,这里的记忆有什么意义呢?

const fetch = React.useMemo(
    () =>
      throttle((request, callback) => {
        autocompleteService.current.getPlacePredictions(request, callback);
      }, 200),
    [],
  );

示例中替换此流程是否更有意义:

useEffect => useMemo => throttle => fetch

只有:

useEffect => throttle => fetch

throttle 是函数创建者:

  • 它的作用:创建另一个函数,其作用是防止重复调用原始函数。 (为了这个答案,定义被过度简化了)。

  • 它没有做的事情:以任何方式执行原始功能。

function throttle(fn, threshhold, scope) {
  return function () {
    let isInvokedRepeatedly = // some programming magic

    if (!isInvokedRepeatedly) {
      fn.apply(context, args);
    }
  };
}

所以如果你像这样在render方法中直接调用throttle()

render() {
  const [inputValue, setInputValue] = React.useState('');
  const fetch = throttle(() => api.request(inputValue));

  ...
}

这意味着每次组件呈现时,都会有一个新的 fetch 实例 re-created,从而重置 throttle 函数的所有内部值。

这可以通过在第一次渲染时使用 useMemouseCallback 仅实例化函数一次并传递一个空数组作为依赖项来解决。

render() {
  const [inputValue, setInputValue] = React.useState('');
  // You can also use React.useMemo()

  // memoize the callback. I personally prefer this method.
  const fetch = React.useCallback(throttle(() => api.request(inputValue)), []);

  // memoize the result which is the callback. Same as above
  const fetch1 = React.useMemo(() => {
    return throttle(() => api.request(inputValue));
  }, [] /* no dependency: callback only run once at startup */);

  ...
}