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
相关产品推荐
相关产品推荐

