简体   繁体   English

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

[英]Debounce on a React functional component when typing not working

I have a form component, and I would like to perform an API request as I am typing.我有一个表单组件,我想在输入时执行 API 请求。 I want to debounce this so I don't spam the server.我想对此进行去抖,这样我就不会向服务器发送垃圾邮件。 Here is my code:这是我的代码:

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>
)
}

The patch item does a simple patch call to the server so that the item's name updates as I am typing.补丁项目对服务器进行简单的补丁调用,以便项目的名称在我键入时更新。 It looks something like this:它看起来像这样:

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

With the debounce it is not working at all.随着去抖动,它根本不起作用。 The patchItem function is never called.永远不会调用patchItem函数。 How can I fix this?我怎样才能解决这个问题?

You're calling debounce on every change to the input but it just creates a new debounced function every time.您在对input每次更改时调用debounce ,但它每次只会创建一个新的 debounce 函数。 You need to create a single debounced function and then use it as event handler.您需要创建一个去抖动函数,然后将其用作事件处理程序。 Like this:像这样:

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>
  );
}

Also make sure the input gets the defaultValue rather than value so it can be edited.还要确保输入获得defaultValue而不是value以便可以对其进行编辑。

There's 2 issues here.这里有2个问题。 Firstly, debounce returns a function, so you need to call that one.首先, debounce返回一个函数,因此您需要调用该函数。

Secondly, if you don't memoize the debounced function then it won't work properly, as each re-render will create a new debounced function, and thus defeat the point of debouncing.其次,如果你不记住去抖动的函数,那么它就不能正常工作,因为每次重新渲染都会创建一个新的去抖动函数,从而失去去抖动的意义。

Try something like this:尝试这样的事情:

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

Make your input controllable, and you can use simple utile use-debounce使您的输入可控,您可以使用简单的实用工具 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.附: you do not have to use bind in your example for sure.您肯定不必在示例中使用 bind 。 and I am not sure you can apply onChange event to form我不确定您是否可以将 onChange 事件应用于表单

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM