打字不起作用时在 React 功能组件上去抖动

Debounce on a React functional component when typing not working

我有一个表单组件,我想在输入时执行 API 请求。我想对此进行去抖动,这样我就不会向服务器发送垃圾邮件。这是我的代码:

export default function MyItem ({ id, name }) {
  const debouncePatch = (name) => {
    debounce(patchItem.bind(this, id, name), 500)
  }
  return (
    <div>
      <form
        type='text'
        value={name}
        onChange={(evt) => debouncePatch(evt.target.value)}
      />
    </div>
)
}

补丁项对服务器进行简单的补丁调用,以便在我输入时更新项的名称。它看起来像这样:

export default function patchItem (id, name,) {
  return axios.patch(`${MY_BASE_URL}/${id}`, { name })
}

有了去抖,它根本不起作用。 patchItem 函数永远不会被调用。我该如何解决这个问题?

让你的输入可控, 你可以使用简单的 utile use-debounce

import { useDebounce } from 'use-debounce';

export default function MyItem ({ id, name }) {
  const [value, setValue] = useState('')
  const [debouncedValue] = useDebounce(value, 1000);

  const handleChange = useCallback((e) => {setValue(e.target.value)}, [])

  useEffect(() => {
    console.log(debouncedValue);
    *// here you can place any code what you need. **console.log** will be displayed every second, or any time that you may change in hook above.* 
  }, [debouncedValue])

  return (
    <div>
      <form
        type='text'
        value={name}
        onChange={handleChange}
      />
    </div>
)
}

ps。你不必在你的例子中肯定使用绑定。我不确定您是否可以将 onChange 事件应用于表单

您在对 input 的每次更改时调用 debounce,但它每次都会创建一个新的去抖动函数。您需要创建一个单一的 debounced 函数,然后将其用作事件处理程序。像这样:

function MyItem({ id, name }) {
  let debouncePatch = debounce((id, name) => {
    patchItem(id, name);
  }, 500);

  // OR SIMPLER
  let debouncePatch = _.debounce(patchItem, 500);
  return (
    <div>
      <input
        type="text"
        defaultValue={name}
        onChange={(event) => debouncePatch(id, event.target.value)}
      />
    </div>
  );
}

还要确保输入得到的是 defaultValue 而不是 value,以便可以对其进行编辑。

这里有 2 个问题。首先,debounce returns一个函数,所以你需要调用那个函数。

其次,如果你不记住去抖动函数,那么它就不能正常工作,因为每个re-render都会创建一个新的去抖动函数,从而破坏去抖动点。

尝试这样的事情:

const debouncePatch = useCallback(debounce(() => patchItem(this, id, name), 500), []);