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

React Native自定义Hook返回值变化时页面不更新的问题排查

问题原因分析

你遇到的核心问题是:ItemListScreen 和 Filter 组件各自调用了 useItems(),这会创建两个完全独立的 Hook 实例,它们的状态(filter、filteredItems 等)是完全隔离的。

当你在 Filter 组件里调用 setFilter 时,修改的是 Filter 内部 Hook 实例的 filter 状态,而 ItemListScreen 里的 filteredItems 属于另一个 Hook 实例,自然不会同步更新。


修复方案

解决思路是让两个组件共享同一个 useItems Hook 的状态实例,常用的两种方法如下:

方法一:状态提升(适合组件层级较浅的场景)

将 useItems 的调用提升到父组件(ItemListScreen),然后通过 props 将 setFilter 传递给 Filter 组件:

修改后的 ItemListScreen 代码

const ItemListScreen = () => {
  const {filteredItems, setFilter} = useItems();

  React.useEffect(() => {
    console.log(filteredItems?.length);
  }, [filteredItems]);

  // 将setFilter通过props传给Filter组件
  return <Filter setFilter={setFilter}/>;
};

export default ItemListScreen;

修改后的 Filter 代码

// 接收父组件传递的setFilter
const Filter = ({setFilter}) => {

  const handleChangeText = (e: string) => {
    setFilter(e);
  };

  return <Input placeholder="Filter" onChangeText={handleChangeText} />
};

export default Filter;

方法二:使用 React Context(适合组件层级较深的场景)

如果后续组件层级变深,props 传递会很繁琐,可以用 Context 来共享 useItems 的状态:

  1. 创建一个 Context 文件:
// ItemContext.js
import React from 'react';

const ItemContext = React.createContext();

export const ItemProvider = ({children}) => {
  const itemsState = useItems();
  return (
    <ItemContext.Provider value={itemsState}>
      {children}
    </ItemContext.Provider>
  );
};

export const useItemContext = () => React.useContext(ItemContext);
  1. 在根组件或父组件中包裹 ItemProvider:
// 比如App.js
import {ItemProvider} from './ItemContext';

function App() {
  return (
    <ItemProvider>
      <ItemListScreen />
    </ItemProvider>
  );
}
  1. 修改 ItemListScreen 和 Filter 组件:
// ItemListScreen.js
const ItemListScreen = () => {
  const {filteredItems} = useItemContext();

  React.useEffect(() => {
    console.log(filteredItems?.length);
  }, [filteredItems]);

  return <Filter/>;
};

// Filter.js
const Filter = () => {
  const {setFilter} = useItemContext();

  const handleChangeText = (e: string) => {
    setFilter(e);
  };

  return <Input placeholder="Filter" onChangeText={handleChangeText} />
};

验证修复效果

修复后,当你在输入框输入筛选词时:

  1. setFilter 修改的是同一个 Hook 实例的 filter 状态
  2. 触发 useItems 中依赖 filter 的 useEffect,重新计算 filteredItems
  3. ItemListScreen 中的 filteredItems 同步更新,对应的 useEffect 会触发并打印新的列表长度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:20:27