Используя библиотеку Flutter Hooks, я получаю конфликт гонки, когда пытаюсь использовать навигатор в использовании.
Flutter Hooks используют документы эффектов
Я отправляю запрос API в своем событии onSubmit, побочным эффектом которого является включение
signupHelper.state.success
к истине. Я хотел бы перейти на другой экран, когда успех == true. Вместо этого я получаю сообщение об ошибке
setState() or markNeedsBuild() called during build
Мой текущий обходной путь - подождать 50 миллисекунд перед навигацией, чтобы убедиться, что перестройка не происходит.
Мой код выглядит так
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import '../hooks/use_signup_helper.dart'
class SignupForm extends HookWidget {
const SignupForm({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
// this wraps useReducer and gives me access to state and dispatch
final signupHelper = useSignupHelper();
useEffect(() {
if (signupHelper.state.success) {
// this is my workaround - delay 50 milliseconds to avoid rebuild conflict
// Future<void>.delayed(const Duration(milliseconds: 50))
// .then((_) => Navigator.pushNamed(context, '/home'));
Navigator.pushNamed(context, '/home'));
}
return null;
}, [signupHelper.state.success]);
return ... // UI goes here
2 ответа
У меня такие же проблемы, и я наткнулся на обернуть
Navigator.push
с
Future.microtask
useEffect(() {
if (condition) {
Future.microtask(() async {
PageResult result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NextPage(),
),
);
if (result == null) {
Navigator.of(context).pop();
} else {
// ...
}
});
}
return;
}, [value]);
Похоже, мы можем использовать классы ScheduleBinding и SchedulerPhase. Импортируется вот так -
import 'package:flutter/scheduler.dart';
И новая функция useEffect выглядит так -
useEffect(() {
if (signupHelper.state.success) {
if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle)
SchedulerBinding.instance.endOfFrame.then((_) {
Navigator.pushNamed(context, '/home');
});
else
Navigator.pushNamed(context, '/home');
}
return null;
}, [signupHelper.state.success]);