You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中使用Lodash Debounce处理TextInput触发异常问题

React Native TextInput防抖失效问题解决

我需要实现React Native的TextInput在输入停止500毫秒后才向API发送请求,但当前每次输入字符都会触发Lodash防抖函数,达不到预期效果。

问题代码

import { debounce } from "lodash";
import React, { FC, useState } from "react"
import { TextInput, View } from "react-native"
interface Props {
}
const LodashInputComponent: FC<Props> = (props) => {
    const [searchText, setSearchText] = useState("");

    const onDebounceSearch = debounce((value: string) => {
        console.log("API Send request", value);
    }, 500);

    const onChangeSearchText = (val: string) => {
        console.log("Change search text", val);
        setSearchText(val);
        onDebounceSearch(val);
    };


    return (
        <View>
            <TextInput
                value={searchText}
                onChangeText={onChangeSearchText}
                placeholder="Search"
            />
        </View>
    )
}
export default LodashInputComponent;

控制台输出(不符合预期)

Change search text h
Change search text he
API Send request h
API Send request he
Change search text hel
Change search text hell
API Send request hel
Change search text hello
API Send request hell
API Send request hello
Change search text hello 
Change search text hello w
Change search text hello wo
API Send request hello 
API Send request hello w
Change search text hello wor
API Send request hello wo
API Send request hello wor
Change search text hello worl
Change search text hello world
API Send request hello worl
API Send request hello world

问题原因

函数组件每次执行(比如调用setSearchText更新state时)都会重新创建onDebounceSearch防抖函数实例。这意味着每次输入字符触发组件重新渲染后,都是在调用一个全新的防抖函数,之前的防抖计时被重置,导致每个字符输入都会触发API请求。


解决方案

方法1:使用useCallback缓存防抖函数

通过useCallback将防抖函数缓存,确保组件渲染时不会重复创建新的防抖实例,同时在组件卸载时清理防抖任务避免内存泄漏。

import { debounce } from "lodash";
import React, { FC, useState, useCallback, useEffect } from "react"
import { TextInput, View } from "react-native"

interface Props {}

const LodashInputComponent: FC<Props> = (props) => {
    const [searchText, setSearchText] = useState("");

    // 用useCallback缓存防抖函数,依赖项为空确保只创建一次
    const onDebounceSearch = useCallback(
        debounce((value: string) => {
            console.log("API Send request", value);
        }, 500),
        []
    );

    const onChangeSearchText = (val: string) => {
        console.log("Change search text", val);
        setSearchText(val);
        onDebounceSearch(val);
    };

    // 组件卸载时取消防抖任务
    useEffect(() => {
        return () => onDebounceSearch.cancel();
    }, [onDebounceSearch]);

    return (
        <View>
            <TextInput
                value={searchText}
                onChangeText={onChangeSearchText}
                placeholder="Search"
            />
        </View>
    )
}

export default LodashInputComponent;

方法2:使用useRef保存防抖函数引用

useRef的.current属性不会随组件渲染变化,适合保存防抖函数实例,确保每次调用的都是同一个防抖函数。

import { debounce } from "lodash";
import React, { FC, useState, useRef, useEffect } from "react"
import { TextInput, View } from "react-native"

interface Props {}

const LodashInputComponent: FC<Props> = (props) => {
    const [searchText, setSearchText] = useState("");
    // 用useRef保存防抖函数实例
    const debounceRef = useRef<(value: string) => void>();

    useEffect(() => {
        // 初始化防抖函数
        debounceRef.current = debounce((value: string) => {
            console.log("API Send request", value);
        }, 500);

        // 卸载时清理防抖任务
        return () => debounceRef.current?.cancel();
    }, []);

    const onChangeSearchText = (val: string) => {
        console.log("Change search text", val);
        setSearchText(val);
        // 调用保存的防抖函数
        debounceRef.current?.(val);
    };

    return (
        <View>
            <TextInput
                value={searchText}
                onChangeText={onChangeSearchText}
                placeholder="Search"
            />
        </View>
    )
}

export default LodashInputComponent;

预期效果

修改后,输入停止500毫秒后只会触发一次API请求。例如输入"hello world",只会在停止输入后打印一次API Send request hello world,不会每个字符输入都触发请求。

内容的提问来源于stack exchange,提问作者Emre Eke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:58:21