River_pod: Explain whey using `read` inside the body of provider is bad

Created on 18 Sep 2020  Â·  12Comments  Â·  Source: rrousselGit/river_pod

In the document you said: It's the bad paractice if we using read inside the body of provider:

Screen Shot 2020-09-18 at 10 10 38

Could you please explain why it is bad/not-good?

documentation

Most helpful comment

It's not about:

final example = Provider((ref) {
  // Bad
  ref.read(anotherProvider);
});

but:

class Example extends ChangeNotifier {
  Example(this.ref);
  final ProviderReference ref;

  void doSomething() {
    // good
    ref.read(anotherProvider);
  }
}

final example = Provider((ref) {
  // Bad
  ref.read(anotherProvider);
});

I'll see if I can reword that. Maybe with a DO/DON'T

All 12 comments

read will not update myProvider when anotherProvider changes

@smiLLe Thank you.
Now I understood.

I asked because in the docs:

Can I read a provider without listening to it?#
Sometimes, we want to read the content of a provider, but without re-creating the value exposed when the value obtained changes.

An example would be a Repository, which reads from another provider the user token for authentification.
We could use watch and create a new Repository whenever the user token changes, but there is little to no use in doing that.

In this situation, we can use read, which is similar to watch, but will not cause the provider to recreate its value exposed when the value obtained changes.

In that case, a common practice is to pass ref.read to the object created. The object created will then be able to read providers whenever it wants.

That means:
We can use ".read" operator inside the body of the provider, right ?
Then after, there is a red alter that said: Don't call .read inside the body of the provider?
That makes me confused.

It's not about:

final example = Provider((ref) {
  // Bad
  ref.read(anotherProvider);
});

but:

class Example extends ChangeNotifier {
  Example(this.ref);
  final ProviderReference ref;

  void doSomething() {
    // good
    ref.read(anotherProvider);
  }
}

final example = Provider((ref) {
  // Bad
  ref.read(anotherProvider);
});

I'll see if I can reword that. Maybe with a DO/DON'T

@rrousselGit Thank you so much for the explanation.

I just would like to confirm that, if we read inside the body of the provider then this one will happen

read will not update myProvider when anotherProvider changes

right? (there is no broken in riverpod)

Also, you can close this issue or keep as reference for update docs as you want.

Thanks!

I just would like to confirm that, if we read inside the body of the provider then this one will happen

That is correct

So the objective of moving the read from inside the body of the provider to the object would be just not to read the anotherProvider just one time, but everytime is needed even though is not watched. Following the Repository example:

  1. If we read inside the provider the token will be read just one time, at creation.
final example = Provider((ref) {
  // Bad the anotherProvider will only be read once, and wont read latest changes.
  ref.read(anotherProvider);
});
  1. In the other hand if we pass down the ProviderReference even tough the example provider will not rebuild on anotherProvider because we don't want it to , each time it calls ref.read will be accessing the last token.
class Example extends ChangeNotifier {
  Example(this.ref);
  final ProviderReference ref;

  void doSomething() {
    // good
    ref.read(anotherProvider);
  }
}

Did I got it right?

That's close enough 🙂

On Fri, Sep 18, 2020, 14:54 fabiancrx notifications@github.com wrote:

So the objective of moving the read from inside the body of the provider
to the object would be just not to read the anotherProvider just one
time, but everytime is needed even though is not watched. Following the
Repository example:

  1. If we read inside the provider the token will be read just one
    time, at creation.

final example = Provider((ref) {
// Bad the anotherProvider will only be read once, and wont read latest changes.
ref.read(anotherProvider);
});

  1. In the other hand if we pass down the ProviderReference even tough
    the example provider will not rebuild on anotherProvider because we
    don't want it to , each time it calls ref.read will be accessing the
    last token.

class Example extends ChangeNotifier {
Example(this.ref);
final ProviderReference ref;

void doSomething() {
// good
ref.read(anotherProvider);
}
}

Did I got it right?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rrousselGit/river_pod/issues/138#issuecomment-694849799,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AEZ3I3LW4IKEW6DHJF2XUWLSGNJ7FANCNFSM4RRK43AQ
.

So, if I do this is a bad practice?

final homeViewModelProvider = Provider(
  (ref) => HomeViewModel(
    ref.read(trackingProvider),
    ref.read(currentRadioProvider).state,
  ),
);

I am trying to inject trackingProvider and radioProvider to my HomeViewModel class.

@juanpare You would do so.

​final homeViewModelProvider = Provider(
  (ref) => HomeViewModel(ref),
); 

And read providers inside your HomeViewModel.

Yes, that's a bad practice. Use watch instead

this is ok?

final homeViewModelProvider = Provider(
  (ref) => HomeViewModel(
    ref.watch(trackingProvider),
    ref.watch(currentRadioProvider).state,
  ),
);

Yes that's fine

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ininmm picture ininmm  Â·  3Comments

logemann picture logemann  Â·  9Comments

0biWanKenobi picture 0biWanKenobi  Â·  5Comments

campanagerald picture campanagerald  Â·  4Comments

hayatae picture hayatae  Â·  7Comments