Code Monkey home page Code Monkey logo

Comments (15)

martinralfreindl avatar martinralfreindl commented on June 4, 2024 1

Can confirm that this is a very common issue I see. I've onboarded multiple juniors onto riverpod, and they all make this mistake at least once.

from riverpod.

noriHanda avatar noriHanda commented on June 4, 2024 1

from riverpod.

nateshmbhat avatar nateshmbhat commented on June 4, 2024 1

can you please add a section in the docs clearly explaning this differences with code examples ?

from riverpod.

timcreatedit avatar timcreatedit commented on June 4, 2024

In some edge-cases you might want to watch the notifier, however, I agree that this is a super common issue for people who are new to Riverpod, and it should generally be discouraged. Any setup where you don't access a notifier via ref.read whenever you want to use it is also often not the best way to do it I've noticed.

from riverpod.

noriHanda avatar noriHanda commented on June 4, 2024

Only valid cases when you want to watch notifier that I know of are onPressed: ref.watch(someProvider.notifier).fire and

@override Widget build(BuildContext context, WidgetRef ref) {
    final notifier = ref.watch(someProvider.notifier);
    return Column(
         children: [
                Button(onPressed: () => notifier.fire('boom')),
                Button(onPressed: () => notifier.fire('beep')),
         ]
    );
}

from riverpod.

PollyGlot avatar PollyGlot commented on June 4, 2024

A bit surprised to see this as a warning, as they return different types. I don't see any case to watch a notifier, but we watch the state (AsyncValue) with a provider.

from riverpod.

rrousselGit avatar rrousselGit commented on June 4, 2024

To me, that's more a misuse of the notifier than a misuse of ref.watch
It is part of the good practices that Notifiers should not expose any state outside of its state field.

There's already a warning telling users not to expose public getters/properties in their notifiers. That notifier.contains(...) in the OP is similar to this. It just bypasses the linter because that's not a getter/property.

There are legitimate use-cases for ref.watch(provider.notifier), especially with the 3.0 where a new Notifier will be recreated when Notifier.build is reinvoked.

Typically this is when using tear-offs:

final notifier = ref.watch(provider.notifier);

return Button(onTap: notifier.increment);

If the notifier were to be recreated, it should re-invoke the build method because the increment method changed.


I could instead see a warning against using Notifier members within build:

Widget build(ctx) {
  final notifier = ref.watch(p.notifier); // OK, no warning

  notifier.doSomething(); // KO, don't use notifier members inside build
}

from riverpod.

timcreatedit avatar timcreatedit commented on June 4, 2024
final notifier = ref.watch(provider.notifier);

return Button(onTap: notifier.increment);

Wouldn't this also be less desirable than

 return Button(onTap: ref.read(provider.notifier).increment);

due to the unnecessary rebuilds?

from riverpod.

rrousselGit avatar rrousselGit commented on June 4, 2024

Wouldn't this also be less desirable than

 return Button(onTap: ref.read(provider.notifier).increment);

due to the unnecessary rebuilds?

No that's incorrect.
Whatever rebuild we have here by using ref.watch is necessary.

If the notifier instance changed, the button must have its onTap method changed to point to the new notifier.

Otherwise you'd be calling increment on a disposed object.

from riverpod.

timcreatedit avatar timcreatedit commented on June 4, 2024

Oh, so in that case the tear-off points to an outdated function? That's crazy, I thought what I wrote would be equivalent to

return Button(onTap: () => ref.read(provider.notifier).increment());

Or am I crazy and that also wouldn't work?

Unrelated, but unnecessary_lambdas is a bit misleading then.

from riverpod.

rrousselGit avatar rrousselGit commented on June 4, 2024

Nope, both variants aren't the same.
That's a common tear-off / variable dereference topic.

unnecessary_lambdas

The warning doesn't appear if a referenced variable is coming from an unknown source. There won't be such an issue here. Otherwise you would see the warning already when using ref.read :)

from riverpod.

timcreatedit avatar timcreatedit commented on June 4, 2024

The warning doesn't appear if a referenced variable is coming from an unknown source. There won't be such an issue here. Otherwise you would see the warning already when using ref.read :)

That's why I said misleading, not wrong :) I'm gonna go out there and suspect that if you survey all Flutter devs, most would think that tear-offs are just syntactic sugar (in part because in some cases, their linter tells them to put them there), but maybe I'm projecting.

Anyway, thanks for the explanation!

from riverpod.

rrousselGit avatar rrousselGit commented on June 4, 2024

This is technically not coming from tear-offs, but how variables behave.

Consider:

int state = 0;
final previousState = state;
state++;

print('$previousState $state'); // prints "0 1"

That's why you should use ref.watch if you write:

final notifier = ref.watch(provider.notifier);

return Button(onTap: () => notifier.increment());

All of that will be covered by a separate lint that spots watch vs read mistakes.

from riverpod.

songyang-dev avatar songyang-dev commented on June 4, 2024

Hi @rrousselGit, thanks for the clarification! I'll keep in mind the differences between watching the provider and the notifier.

from riverpod.

songyang-dev avatar songyang-dev commented on June 4, 2024

can you please add a section in the docs clearly explaning this differences with code examples ?

Consider starting a new issue for this if there isn't already one.

from riverpod.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.