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

Riverpod问题:如何向数据库传不同值实现搜索栏实时查询

问题解决思路

核心问题在于你当前watch的是固定参数''的searchResultsProvider实例,即便你在onChanged里refresh其他参数的provider实例,组件依赖的始终是空字符串对应的provider,因此不会触发重建。

正确的做法是通过一个状态提供者存储当前搜索关键词,让组件依赖这个状态,自动根据关键词切换要watch的FutureProvider.family实例。

具体修改步骤

1. 添加存储搜索关键词的StateProvider

// 用于保存当前输入的搜索关键词
final currentSearchQueryProvider = StateProvider<String>((ref) => '');

2. 修改TextField的onChanged逻辑

不再直接refresh provider,而是更新上述StateProvider的状态:

TextField(
  onChanged: (value) {
    // 更新当前搜索关键词状态
    ref.read(currentSearchQueryProvider.notifier).state = value;
  },
)

3. 调整组件内的watch逻辑

先获取当前搜索关键词,再用它来watch对应的FutureProvider实例:

Widget build(BuildContext context) {
  // 先监听当前搜索关键词的变化
  final currentQuery = ref.watch(currentSearchQueryProvider);
  // 根据当前关键词监听对应的搜索结果provider
  final searchResults = ref.watch(searchResultsProvider(currentQuery));

  // 后续根据searchResults的状态处理UI(加载中、数据展示、错误提示)
  return searchResults.when(
    loading: () => const CircularProgressIndicator(),
    error: (err, stack) => Text('搜索出错: $err'),
    data: (results) => ListView.builder(
      itemCount: results.length,
      itemBuilder: (context, index) => ListTile(
        title: Text(results[index]['title']), // 示例字段,根据实际数据调整
      ),
    ),
  );
}

原Provider代码无需修改

final searchResultsProvider = FutureProvider.autoDispose
    .family<List<Map<String, dynamic>>, String>((ref, value) async {
  final data = await dbGetSearchResults(value);
  return data;
});

原理说明

  • currentSearchQueryProvider的状态变化会触发组件重建,每次输入新关键词时,组件会自动切换到watch对应关键词的searchResultsProvider实例。
  • 由于使用了autoDispose,当关键词切换后,旧关键词对应的provider实例会被自动销毁,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:53:24