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

Flutter中如何用Riverpod实现下拉框联动刷新表格Widget?

问题根源

你的表格组件未重渲染的核心原因是:dashboardRepositoryProvider是普通Provider,它返回的DashboardRepository实例引用从未改变——即便你在fetchDashboard里更新了实例内部的_data变量,Riverpod也不会因为对象内部状态变化而通知监听者。普通Provider仅当返回的对象本身被替换时,才会触发组件重建。


解决方案

方案一:直接监听fetchDashboardData FutureProvider

既然你已经通过ref.refresh(fetchDashboardData(newValue))触发了数据请求,只需让表格组件监听这个FutureProvider的状态即可:

修改TableGenerator组件

class TableGenerator extends ConsumerWidget {
  // 接收当前选中的下拉框值,用于指定监听的Family实例
  final String selectedName;
  const TableGenerator({Key? key, required this.selectedName}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 监听对应name的fetchDashboardData状态
    final dashboardAsync = ref.watch(fetchDashboardData(selectedName));

    return dashboardAsync.when(
      loading: () => const CircularProgressIndicator(),
      error: (err, stack) => Text('加载失败:$err'),
      data: (_) {
        // 数据加载完成后从仓库取最新值
        final repo = ref.watch(dashboardRepositoryProvider);
        return SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Row(
            children: [
              const FixedColumnWidget(data: [
                "one",
                "two",
                "three",
                "four",
                "fifth",
              ]),
              ScrollableColumnWidget(data: repo.dashboardData as DashboardData)
            ],
          ),
        );
      },
    );
  }
}

在父组件中传入选中值

// 示例:在使用TableGenerator的地方
final selectedName = ref.watch(dropItemProvider);
TableGenerator(selectedName: selectedName)

当你调用ref.refresh(fetchDashboardData(newValue))时,FutureProvider的状态会更新,触发TableGenerator重建并渲染新数据。


方案二:用StateNotifierProvider管理可监听状态(推荐)

这是更符合Riverpod规范的做法,通过StateNotifier封装状态,让状态变化自动触发组件重建:

1. 重构仓库为StateNotifier

import 'package:flutter_riverpod/flutter_riverpod.dart';

class DashboardStateNotifier extends StateNotifier<DashboardData?> {
  DashboardStateNotifier(this.read) : super(null);
  
  final Reader read;

  List<dynamic>? _names;
  List<dynamic>? get names => _names;

  Future<void> fetchDashboard(String name) async {
    final token = await read(authServiceProvider).getToken();
    final response = await read(clientProvider(token))
        .get('/getData', queryParameters: {"name": name});
    
    // 更新state,自动通知所有监听者
    state = DashboardData.fromJson(response.data);
  }

  Future<void> fetchNames() async {
    final token = await read(authServiceProvider).getToken();
    final response = await read(clientProvider(token)).get('/analystNames');
    _names = response.data["names"];
  }
}

2. 创建对应的Provider

final dashboardStateProvider = StateNotifierProvider<DashboardStateNotifier, DashboardData?>((ref) {
  return DashboardStateNotifier(ref.read);
});

// 保留获取名称的FutureProvider
final fetchAnalystNames = FutureProvider((ref) {
  final notifier = ref.watch(dashboardStateProvider.notifier);
  return notifier.fetchNames();
});

3. 修改下拉框回调

onChanged: (String? newValue) {
  if (newValue == null) return;
  ref.read(dropItemProvider.notifier).state = newValue;
  // 直接调用notifier方法更新状态
  ref.read(dashboardStateProvider.notifier).fetchDashboard(newValue);
  setState(() {
    widget.value = newValue;
  });
},

4. 修改TableGenerator组件

class TableGenerator extends ConsumerWidget {
  const TableGenerator({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 监听StateNotifier的状态
    final dashboardData = ref.watch(dashboardStateProvider);

    return dashboardData != null
        ? SingleChildScrollView(
            scrollDirection: Axis.vertical,
            child: Row(
              children: [
                const FixedColumnWidget(data: [
                  "one",
                  "two",
                  "three",
                  "four",
                  "fifth",
                ]),
                ScrollableColumnWidget(data: dashboardData)
              ],
            ))
        : const CircularProgressIndicator();
  }
}

这种方式将状态与UI解耦,状态变化会自动触发组件重建,无需手动处理刷新逻辑,是Riverpod推荐的状态管理方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:48:24