关于 Flutter_riverpod 的使用

huangapple go评论57阅读模式
英文:

About Flutter_riverpod usage

问题

当我写 Text(company.dataArea.toString()) 时,我可以在同一个页面上读取已更改的值,但我无法在另一页上读取该值。我应该怎么做?

英文:

I had a question regarding the use of riverpod.

This is my first time using the Riverpod. But I'm not sure if I'm using it correctly.

Definitions:

class CompanyModel {
  String? dataArea;

  CompanyModel({this.dataArea});
}
class RiverpodCompany extends StateNotifier<CompanyModel> {
  RiverpodCompany() : super(CompanyModel(dataArea: "Test"));

  updateDataArea(value) {
    return state = CompanyModel(dataArea: value);
  }
}

HomePage:

final riverpodChangeCompany =
    StateNotifierProvider<RiverpodCompany, CompanyModel>(
  (ref) => RiverpodCompany(),
);

class HomePage extends ConsumerWidget {
  const HomePage({super.key});
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    TextEditingController tfController = TextEditingController();
    final company = ref.watch(riverpodChangeCompany);
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(company.dataArea.toString()),
            SizedBox(
              width: 200,
              child: TextField(
                controller: tfController,
              ),
            ),
            const SizedBox(
              height: 15,
            ),
            SizedBox(
              width: 100,
              height: 100,
              child: GestureDetector(
                onTap: () {
                  ref
                      .watch(riverpodChangeCompany.notifier)
                      .updateDataArea(tfController.text);
                  print(tfController.text);
                  Navigator.pushNamed(context, AppRoutesNames.finalpage);
                },
                child: const Card(
                  color: Colors.blueAccent,
                  child: Center(child: Text("OK")),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

When i write Text(company.dataArea.toString()) I can read the changed value in the same page but i cannot read this value on another page. What should i do?

答案1

得分: 1

With Riverpod 2.0 you can create without looking back at technical limitations. Thank you Rém i Rousselet!

This is what your domain/controllerUI part might look like:

@immutable
class CompanyModel {
  const CompanyModel({this.dataArea});

  final String? dataArea;
}

final companyNotifier =
    NotifierProvider<CompanyNotifier, CompanyModel>(CompanyNotifier.new);

class CompanyNotifier extends Notifier<CompanyModel> {
  @override
  CompanyModel build() {
    /// In this method you can use `ref.watch` to track other providers
    return const CompanyModel(dataArea: "Test");
  }

  void updateDataArea(String? value) {
    // Here you have access to `ref.read` to read other providers
    state = CompanyModel(dataArea: value);
  }
}

Your models must(!) be immutable and the fields immutable. This will help avoid a lot of problems. Also, use const in the constructor. It might be worth taking a closer look at freezed while we wait for metastatic programming.

Your interface will look like this:

class Page1 extends ConsumerWidget {
  const Page1({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final company = ref.watch(companyNotifier);
    final notifier = ref.watch(companyNotifier.notifier);

    return Scaffold(
      body: Column(
        children: [
          Text('PAGE1 : ${company.dataArea ?? ''}'),
          IconButton(
              onPressed: () {
                notifier.updateDataArea('From Page1');
                Navigator.pushNamed(context, 'page2');
              },
              icon: const Icon(Icons.ac_unit)),
        ],
      ),
    );
  }
}

class Page2 extends ConsumerWidget {
  const Page2({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final company = ref.watch(companyNotifier);
    final notifier = ref.watch(companyNotifier.notifier);

    return Scaffold(
      body: Column(
        children: [
          Text('PAGE2 : ${company.dataArea ?? ''}'),
          IconButton(
              onPressed: () {
                notifier.updateDataArea('From Page2');
                Navigator.pushNamed(context, 'page3');
              },
              icon: const Icon(Icons.ac_unit)),
        ],
      ),
    );
  }
}

I should also note that in the callbacks you should use ref.watch instead of ref.read.

英文:

With Riverpod 2.0 you can create without looking back at technical limitations. Thank you Rémi Rousselet!

This is what your domain/controllerUI part might look like:

@immutable
class CompanyModel {
  const CompanyModel({this.dataArea});

  final String? dataArea;
}

final companyNotifier =
    NotifierProvider<CompanyNotifier, CompanyModel>(CompanyNotifier.new);

class CompanyNotifier extends Notifier<CompanyModel> {
  @override
  CompanyModel build() {
    /// In this method you can use `ref.watch` to track other providers
    return const CompanyModel(dataArea: "Test");
  }

  void updateDataArea(String? value) {
    // Here you have access to `ref.read` to read other providers
    state = CompanyModel(dataArea: value);
  }
}

Your models must(!) be immutable and the fields immutable. This will help avoid a lot of problems. Also, use const in the constructor. It might be worth taking a closer look at freezed while we wait for metastatic programming.

Your interface will look like this:

class Page1 extends ConsumerWidget {
  const Page1({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final company = ref.watch(companyNotifier);
    final notifier = ref.watch(companyNotifier.notifier);

    return Scaffold(
      body: Column(
        children: [
          Text('PAGE1 : ${company.dataArea ?? ''}'),
          IconButton(
              onPressed: () {
                notifier.updateDataArea('From Page1');
                Navigator.pushNamed(context, 'page2');
              },
              icon: const Icon(Icons.ac_unit)),
        ],
      ),
    );
  }
}

class Page2 extends ConsumerWidget {
  const Page2({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final company = ref.watch(companyNotifier);
    final notifier = ref.watch(companyNotifier.notifier);

    return Scaffold(
      body: Column(
        children: [
          Text('PAGE2 : ${company.dataArea ?? ''}'),
          IconButton(
              onPressed: () {
                notifier.updateDataArea('From Page2');
                Navigator.pushNamed(context, 'page3');
              },
              icon: const Icon(Icons.ac_unit)),
        ],
      ),
    );
  }
}

I should also note that in the callbacks you should use ref.watch instead of ref.read.

huangapple
  • 本文由 发表于 2023年4月11日 16:30:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75983876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定