我正在玩React Native和lodash的辩护。
使用以下代码只会使其像延迟一样工作,而不是去抖动。
<Input
onChangeText={(text) => {
_.debounce(()=> console.log("debouncing"), 2000)()
}
/>
如果输入“foo”之类的输入,我希望控制台只记录一次debounce。现在它记录了3次“去抖动”。
答案 0 :(得分:43)
去抖函数应该在render方法之外的某个地方定义,因为每次调用它时它都必须引用函数的同一个实例,因为它反对创建一个新的实例,就像现在你把它放在{{1处理函数。
定义去抖功能的最常见位置是在组件的对象上。这是一个例子:
onChangeText
答案 1 :(得分:2)
尝试了许多不同的方法后,我发现使用“ useCallback”是解决多重调用问题的最简单,最有效的方法。
根据Hooks API documentation,“ useCallback返回一个记忆的回调版本,只有在其中一个依赖项已更改时,该回调版本才会更改。”
传递一个空数组作为依赖项,以确保仅调用一次回调。这是一个简单的实现。
import React, { useCallback } from "react";
import { debounce } from "lodash";
const handler = useCallback(debounce(someFunction, 2000), []);
const onChange = (event) => {
// perform any event related action here
handler();
};
希望这会有所帮助!
答案 2 :(得分:0)
正如其他答案已经说明的那样,去抖动函数引用必须创建一次,并通过调用相同的引用来取消相关函数(即在我的示例中为 changeTextDebounced
)。对@George Borunov
的回答稍作改动就可以解决问题。
class SomeClassComponent extends React.Component {
componentDidMount = () => {
this.changeTextDebouncer = _.debounce(this.changeTextDebounced, 500);
}
changeTextDebounced = (text) => {
console.log("debounced");
}
render = () => {
return <Input onChangeText={this.changeTextDebouncer} />;
}
}
答案 3 :(得分:-2)
在这里您可以找到一个很好的使用方法示例:
import React, { useState } from 'react';
import _ from 'lodash';
import { fetchData } from '../../services/request';
import ResultListComponent from '../ResultList';
const SearchBarComponent = () => {
const [query, setQuery] = useState('');
const [searchQuery, setSearchQuery] = useState({});
const [dataList, setDataList] = useState([]);
const [errorMssg, setErrorMssg] = useState('');
/**
* This will be called every time there is
* a change in the input
* @param {*} { target: { value } }
*/
const onChange = ({ target: { value } }) => {
setQuery(value);
// Here we set search var, so debounce will make sure to trigger
// the event every 300ms
const search = _.debounce(sendQuery, 300);
setSearchQuery(prevSearch => {
// In case there is a previous search triggered,
// cancel() will prevent previous method to be called
if (prevSearch.cancel) {
prevSearch.cancel();
}
return search;
});
search(value);
};
/**
* In charge to send the value
* to the API.
* @param {*} value
*/
const sendQuery = async value => {
const { cancelPrevQuery, result } = await fetchData(value);
if (cancelPrevQuery) return;
if (result.Response === 'True') {
setDataList(result.Search);
setErrorMssg('');
} else {
setDataList([]);
setErrorMssg(result.Error);
}
};
return (
<div>
<div>
<p>Type to search!</p>
<input type="text" value={query} placeholder="Enter Movie Title" onChange={onChange} />
</div>
<div>
<ResultListComponent items={dataList} />
{errorMssg}
</div>
</div>
);
};
export default SearchBarComponent;
您可以参考我刚刚写的这篇中等文章:
https://medium.com/@mikjailsalazar/just-another-searchbar-react-axios-lodash-340efec6933d