javascript - React.js 中功能组件内部的反跳

标签 javascript reactjs react-hooks lodash debouncing

尝试在具有随更改而更新的输入字段的 react 组件上创建延迟。

代码如下:

import React from 'react'; 
import Input from "@material-ui/core/Input";
import {debounce} from "lodash";
...

const SampleRow = () => {
    let [newFriend, setNewFriend] = React.useState({name: '', lastSeen: '', contactIn: ''});

    const onAddFriend = debounce(() => {
        if(newFriend.name.length === 0){
            return;
        }
        console.log(newFriend.name);
    }, 2000);

    return (
        <TableRow>
            <TableCell component="th" scope="row">
                <Input
                    value={newFriend.name}
                    onChange={(event) => {
                        setNewFriend({...newFriend, name: event.target.value});
                        onAddFriend();
                    }}
                    placeholder={"Add friend"}
                    disableUnderline={true}
                />
            </TableCell>
            <TableCell align="left">{newFriend.lastSeen ? newFriend.lastSeen : ''}</TableCell>
            <TableCell align="left">{newFriend.contactIn ? newFriend.contactIn : ''}</TableCell>
            <TableCell align="left" className={classes.externalLinks}/>
        </TableRow>
    )
};

发生的情况是,console.log 打印出每个更改(在 2 秒超时后),并且不会取消之前的触发器。

问题是为什么会发生这种情况?如何解决这个问题?

I've found similar questions with complex useDebounce logic or class-components. Didn't find a reference for this problem.

最佳答案

这里的问题是,每次渲染时都会重新创建去抖函数。

解决此问题的一种方法是将其移出功能组件。另一种方法是将组件更改为类组件并将去抖函数保存为属性。

const { useState } = React
const { debounce } = _;

const onAddFriend = debounce(console.log, 2000);

const App = () => {
 
  const [newFriend, setNewFriend] = useState({name: '',   lastSeen: '', contactIn: ''});
  
  const handleInput = (event) => {
    setNewFriend({...newFriend, name: event.target.value});
    onAddFriend(event.target.value);
  }
  
  return (
    <div className="box">
      <form className="form">
        <div class="field">
          <label for="name-1">Update  {newFriend.name}</label>
          <div class="control">
            <input type="text" name="name-1" value={newFriend.name}
                    onChange={handleInput} class="input"/>
          </div>
        </div>
      </form>
    </div>
  )
}

ReactDOM.render(<App />,
document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>
<script src="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3042555153447001061e071e001d515c4058511e00" rel="noreferrer noopener nofollow">[email protected]</a>/umd/react.production.min.js"></script>
<script src="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5321363230277e373c3e1362657d647d637e323f233b327d63" rel="noreferrer noopener nofollow">[email protected]</a>/umd/react-dom.production.min.js"></script>

<div id="root"></div>

关于javascript - React.js 中功能组件内部的反跳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62937894/

相关文章:

javascript - 我可以提前结束 Promise.each 吗?

javascript - 从 Javascript 在 Textarea 中搜索链接

css - 如何在 React 组件中应用渐变动画效果

reactjs - Jest : Cannot read property 'secondary' of undefined - after MUI upgrade from V4 toV5

php - 获取哈希 URL 并将其发送到新 URL

javascript - 来自关联数组的树

javascript - react /归零 : Should containers have any knowledge of state structure?

reactjs - 如何在 React Hooks 中更改 props 到 state?

reactjs - 为什么在react中需要点击两次才能执行状态更改?

javascript - Reactjs app div onclick 在 IE 11 中不起作用,没有调用任何函数