Используя библиотеку 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]);
Другие вопросы по тегам