React:当用户停止输入时触发函数
React : Trigger function when the user stops typing
我正在使用带有异步创建 table 的 react-select 并将其实现到 Netsuite 自定义页面。问题是我想加载 getAsyncOptions 函数以仅在用户停止键入时触发。目前,这些代码行使输入字段变得如此缓慢,因为每次将字母添加到输入时都会触发该功能。我也无法将获取的数据插入状态,因为它将填充一千条记录。
Email.tsx
getAsyncOptions(inputValue) {
return new Promise((resolve) => {
var typingTimer; //timer identifier
var doneTypingInterval = 1000; //time in ms (1 second)
if (inputValue.length <= 3) {
return resolve([]);
}
clearTimeout(typingTimer);
if (inputValue) {
return (typingTimer = setTimeout(function () {
var t0 = performance.now();
emailSearch(inputValue).then((data) => {
const returnData = [];
data.forEach((contact) => {
returnData.push({
label: contact.email + " - (" + contact.company + ")",
value: contact.email,
});
});
resolve(returnData);
console.log(
"Call to email search function took " +
(t1 - t0) +
" milliseconds."
);
});
var t1 = performance.now();
}, doneTypingInterval));
}
});
正如您在上面的代码中看到的,它只是延迟了代码的触发。而另一个问题是当用户停止打字1秒再继续打字时,它只是在延迟功能,每1秒触发一次。剩下的代码供大家参考。
RenderOpenMode.tsx
<AsyncCreatableSelect
value={props.state.toEmailCollection}
onChange={props.setToEmail}
loadOptions={props.debouncedLoadQuery}
styles={props.customSelectStylesEmail}
components={{
DropdownIndicator: () => null,
IndicatorSeparator: () => null,
}}
isMulti={true}
isSearchable={true}
isValidNewOption={props.isValidNewOption}
placeholder=""
/>
函数
this.setToEmail = (toEmailCollection) =>
this.setState({ toEmailCollection: toEmailCollection });
this.setToCc = (toCcCollection) =>
this.setState({ toCcCollection: toCcCollection });
const loadOptions = (inputValue) => this.getAsyncOptions(inputValue));
this.debouncedLoadQuery = debounce(loadOptions, 2000, {
leading: true,
});
遇到这个障碍已经有一段时间了,非常感谢任何想法或帮助!非常感谢,上帝保佑!
编辑:
添加了一些代码。 onChange 只更新一些状态,问题是 loadOptions 因为它是触发 getAsyncOptions 的那个。
我已经解决了这个问题,看来问题出在去抖动上。我正在使用 debounce-promise,问题是我使用了 leading=true 选项,这使得 UI 对更改没有响应。
来自这段代码:
this.debouncedLoadQuery = debounce(loadOptions, 2000, {
leading: true,
});
到此代码:
this.debouncedLoadQuery = debounce(loadOptions, 2000);
我正在使用带有异步创建 table 的 react-select 并将其实现到 Netsuite 自定义页面。问题是我想加载 getAsyncOptions 函数以仅在用户停止键入时触发。目前,这些代码行使输入字段变得如此缓慢,因为每次将字母添加到输入时都会触发该功能。我也无法将获取的数据插入状态,因为它将填充一千条记录。
Email.tsx
getAsyncOptions(inputValue) {
return new Promise((resolve) => {
var typingTimer; //timer identifier
var doneTypingInterval = 1000; //time in ms (1 second)
if (inputValue.length <= 3) {
return resolve([]);
}
clearTimeout(typingTimer);
if (inputValue) {
return (typingTimer = setTimeout(function () {
var t0 = performance.now();
emailSearch(inputValue).then((data) => {
const returnData = [];
data.forEach((contact) => {
returnData.push({
label: contact.email + " - (" + contact.company + ")",
value: contact.email,
});
});
resolve(returnData);
console.log(
"Call to email search function took " +
(t1 - t0) +
" milliseconds."
);
});
var t1 = performance.now();
}, doneTypingInterval));
}
});
正如您在上面的代码中看到的,它只是延迟了代码的触发。而另一个问题是当用户停止打字1秒再继续打字时,它只是在延迟功能,每1秒触发一次。剩下的代码供大家参考。
RenderOpenMode.tsx
<AsyncCreatableSelect
value={props.state.toEmailCollection}
onChange={props.setToEmail}
loadOptions={props.debouncedLoadQuery}
styles={props.customSelectStylesEmail}
components={{
DropdownIndicator: () => null,
IndicatorSeparator: () => null,
}}
isMulti={true}
isSearchable={true}
isValidNewOption={props.isValidNewOption}
placeholder=""
/>
函数
this.setToEmail = (toEmailCollection) =>
this.setState({ toEmailCollection: toEmailCollection });
this.setToCc = (toCcCollection) =>
this.setState({ toCcCollection: toCcCollection });
const loadOptions = (inputValue) => this.getAsyncOptions(inputValue));
this.debouncedLoadQuery = debounce(loadOptions, 2000, {
leading: true,
});
遇到这个障碍已经有一段时间了,非常感谢任何想法或帮助!非常感谢,上帝保佑!
编辑: 添加了一些代码。 onChange 只更新一些状态,问题是 loadOptions 因为它是触发 getAsyncOptions 的那个。
我已经解决了这个问题,看来问题出在去抖动上。我正在使用 debounce-promise,问题是我使用了 leading=true 选项,这使得 UI 对更改没有响应。
来自这段代码:
this.debouncedLoadQuery = debounce(loadOptions, 2000, {
leading: true,
});
到此代码:
this.debouncedLoadQuery = debounce(loadOptions, 2000);