New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useEffect hook not working properly. #153
Comments
show your implementation with flutter_hooks |
You cannot perform operation with the context API inside That doesn't work: useEffect() => {
useContext(MyContext); // not a valid usage
}, []); |
Although arguably, we could allow calling Provider's |
@rrousselGit For example. Then I used this hook and it worked as expectedly. |
Instead do: final bundle = DefaultAssetBundle.of(context);
useEffect(() {
bundle.loadString('...').then(...);
}, [bundle]); |
It works, thanks @rrousselGit . |
@rrousselGit What's the proper way to use a I get this error without it:
@freezed
abstract class AppState with _$AppState {
const factory AppState({
@Default(false) bool hasOnboarded,
Widget fab,
@Default([]) List<DepartmentModel> favorites,
}) = _AppState;
}
final stateProvider = StateProvider((_) => const AppState());
final stateController = useProvider(stateProvider);
useEffect(() {
// Future.microtask(() {
stateController.state = stateController.state.copyWith(
fab: FloatingActionButton(
backgroundColor: theme.accentColor,
onPressed: () {},
child: const Icon(Icons.share),
),
);
// });
return () {
// Future.microtask(() {
stateController.state = stateController.state.copyWith(fab: null);
// });
};
}, [stateController]); |
It is required. The exception was implemented on purpose to prevent modifying a provider inside build without the microtask because that is dangerous. |
I figured, thanks. Pretty trivial to add my own void useAsyncEffect(
FutureOr<dynamic> Function() effect,
FutureOr<dynamic> Function() cleanup, [
List<Object> keys,
]) {
useEffect(() {
Future.microtask(effect);
return () {
if (cleanup != null) {
Future.microtask(cleanup);
}
};
}, keys);
} |
This is my version of void useAsyncEffect(Future<Dispose?> Function() effect, [List<Object?>? keys]) {
useEffect(() {
final disposeFuture = Future.microtask(effect);
return () => disposeFuture.then((dispose) => dispose?.call());
}, keys);
} |
Closing since everything is working as expected. I don't plan on adding a |
@rrousselGit Can you elaborate please why is this a sign of code smell? I have many places in my code where a firs-time useEffect calls an async function.. some might use the context too. Why is this bad? 🙂 |
Because if your problem is "can't call setState", the solution isn't to silence the error by using a hacky workaround of delaying the update by a frame You should refactor your code such that the update is performed before all listeners of the object were built. |
Oh okay, I thought calling async funcs in useEffect is considered bad in general.. 😅 Thanks @rrousselGit! |
Thanks for your explanation. Here is the code: nextPage() {
Navigator.of(context).push(
MaterialPageRoute(
maintainState: false,
builder: (context) => LobbyPage(),
),
);
}
// final acconutNotifier = ref.watch(accountProvider.notifier);
final loginFuture = useMemoized(() => () async {
controller.forward(); // animation
final acconutNotifier = ref.read(accountProvider.notifier);
await acconutNotifier.login();
nextPage();
}());
useFuture(loginFuture); |
In React, useEffect hook works after first build. Bu in flutter_hooks, useEffect works before first render. That's why, make an operation with context object on useEffect(() { //operation using context }, []) makes following error:
Cannot listen to inherited widgets inside HookState.initState. Use HookState.build instead.
REACT HOOKS WORKING EXAMPLE
The text was updated successfully, but these errors were encountered: