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

React中如何避免搜索输入变化时因依赖更新触发useEffect执行?

解决搜索输入时validateUser重复执行的问题

问题根源

每次在搜索框输入内容时,searchValue变化会触发组件重渲染,而你的useList钩子中,list是每次渲染都通过_.cloneDeep和filter生成的新数组(引用地址不同),导致useEffect的依赖list每次都变化,进而重复执行validateUser。另外你的列表过滤逻辑存在依赖缺失问题,搜索输入后列表不会正确更新,这个也顺便修正。

具体解决方案

1. 缓存useList中的list,避免不必要的引用变化

修改useList钩子,用useMemo缓存list和otherMenus,只有当接口返回的data变化时才重新生成:

export default function useMenu() {
  const { data } = useQuery(GET_LIST)
  
  const list = useMemo(() => {
    return _.cloneDeep(data)?.menuTree?.filter((i) => i.parentId === null) || []
  }, [data])

  const otherMenus = useMemo(() => {
    return data?.menuTree || []
  }, [data])

  return { list, otherMenus }
}

这样搜索输入时,data没有变化,list的引用就会保持稳定,不会触发useEffect的重复执行。

2. 修正列表过滤的依赖问题(可选但必要)

当前的allLists依赖中缺少searchValue,导致搜索输入后列表不会更新。需要把searchValue作为参数传入过滤函数,并添加到useMemo依赖中:

const getFilteredElements = (items, searchValue) => {
  let parentMatched = false

  const filteredItems = items.filter((item) => {
    if (item.title.toLowerCase().includes(searchValue.toLowerCase())) {
      parentMatched = true
      return true
    }
    
    return false
  })

  return { filteredItems, parentMatched }
}

const createListBasedOnUser = (items, searchValue, filterChildren = false) => {
  const { filteredItems, parentMatched } = getFilteredElements(items, searchValue)
  const result = []

  for (const item of filterChildren ? items : filteredItems) {
    result.push({
      title: item.title,
    })
  }
  return result // 原代码未返回结果,此处补充
}

const allLists = useMemo(() => {
  const elements = createListBasedOnUser(list, searchValue, false)
  return elements ? [...elements] : []
}, [list, collapsed, searchValue]) // 添加searchValue到依赖

3. 确保validateUser函数稳定(如果是组件内定义)

如果validateUser是在当前组件内部定义的函数,每次组件重渲染它都会生成新的引用,也可能间接导致问题,需要用useCallback缓存:

const validateUser = useCallback((currentUser, list) => {
  // 你的validateUser逻辑
}, []) // 此处添加函数内部用到的外部依赖变量

内容的提问来源于stack exchange,提问作者Mir Stephen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:07:06