簡體   English   中英

Flutter Riverpod Statenotifier 應在 map 更改時重建

[英]Flutter Riverpod Statenotifier should rebuild on map changes

當 map 更改時,我的 statenotifier 不會重建。 我認為問題在於 map 在另一個 class 內。 我使用riverpod,並且我已經看到它可以與列表一起使用,因此我在class 中使用列表進行了測試,並將過濾器重建為該class。 但沒有成功

StateNotifier using copyWith to replace a map does not trigger rebuild
class Admin {
  const Admin({
    this.admin = const {},
  });

  final Map<int, List<String>> admin;

  Admin copyWith({
    Map<int, List<String>>? admin,
  }) {
    return Admin(
      admin: admin ?? this.admin,
    );
  }
}

class Member {
  const Member({
    this.wordOfTheDay = "",
    this.admin = const Admin(),
  });

  final Admin admin;
  final String wordOfTheDay;

  Member copyWith({
    Admin? admin,
    String? wordOfTheDay,
  }) {
    return Member(
      admin: admin ?? this.admin,
      wordOfTheDay: wordOfTheDay ?? this.wordOfTheDay,
    );
  }
}

class MemberNotifier extends StateNotifier<AsyncValue<Member>> {
  MemberNotifier() : super(const AsyncValue.loading());

  final Map<int, List<String>> admins = {};

  void loadMembers(String id, String item) {
    admins[id]!.add(item);
    state = state.whenData((value) => value.copyWith(admin: state.value!.admin.copyWith(admin: admins)));
  }
}

final watch = ref.watch(memberNotifierProvider.select((member) => member.value!.admin));

我今天正在解決一個類似的問題,即使用 Freezed 和 Riverpod 無法正確復制地圖。 我正在閱讀這個 github 問題,也許它也會對您有所幫助。 https://github.com/rrousselGit/freezed/issues/185

我們可以傳遞 Map 值並在 Map<String,dynamic> 中設置值,如下所示:-

提供者

 final counterProvider =
        StateNotifierProvider<Counter, Map<String, dynamic>>((_) => Counter());

class Counter extends StateNotifier<Map<String, dynamic>> {
  // Counter(Map<String, dynamic> data): super(data);
  Counter() : super({});

  void displayFile(String name, String email, String address) {
    Map<String, dynamic> cartMap = {"name": name, "email": email, "address": address};

    state = {...state, ...cartMap};
  }
}

之后,我們可以在 Riverpod 中使用 HooksConsumerWidget 獲取 Map 的值:-

class MyHomePage extends HookConsumerWidget {
  MyHomePage({Key? key}) : super(key: key);

  TextEditingController nameController = TextEditingController();
  TextEditingController emailController = TextEditingController();
  TextEditingController addressController = TextEditingController();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final dataValue = ref.watch(counterProvider);
    String name = dataValue['name'].toString();
    String email = dataValue['email'].toString();
    String address = dataValue['address'].toString();
    print(dataValue);
    return Scaffold(
        appBar: AppBar(
          title: const Text(' demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(15.0),
          child: Column(
            children: [
              TextFormField(
                controller: nameController,
                keyboardType: TextInputType.text,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: 'Enter name',
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              TextFormField(
                controller: emailController,
                keyboardType: TextInputType.text,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: 'Enter email',
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              TextFormField(
                controller: addressController,
                keyboardType: TextInputType.text,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: 'Enter address',
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              ElevatedButton(
                  onPressed: () {
                    ref.read(counterProvider.notifier).displayFile(
                        nameController.text,
                        emailController.text,
                        addressController.text);
                  },
                  child: const Text('Show Details')),
              const SizedBox(
                height: 20,
              ),
              Text(name),
              const SizedBox(
                height: 10,
              ),
              Text(email),
              const SizedBox(
                height: 10,
              ),
              Text(address),
            ],
          ),
        ));
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM