Остановить рекурсивный рендеринг виджета из-за провайдера (я думаю, неправильное использование) - PullRequest
2 голосов
/ 27 апреля 2020

Проблема

Рекурсивный рендеринг виджета из-за неправильного (возможно) использования провайдера.

Это main.dart:

void main() {
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider<NotesProvider>(
        create: (_) => NotesProvider(),
      ),
      ChangeNotifierProvider<ThemeProvider>(
        create: (_) => ThemeProvider(),
      ),
    ],
    child: MyApp(),
  ));
}

Это перенаправляет на outer_page, который содержит две вкладки, подобные этой:

image

Это код выглядит так:

class OuterPage extends StatefulWidget {
  static const routeName = '/OuterPage';
  @override
  State<StatefulWidget> createState() {
    return OuterPageState();
  }
}

class OuterPageState extends State<OuterPage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  int _selectedTab = 0;
  final _pageOptions = [
    NoteScreen(),                       // <- Notes Tab
    NotePageScreen(),              // <- 'Another' Tab
  ];

Widget build(BuildContext context) {
    var noteProvider = Provider.of<NotesProvider>(context, listen: false);
    // https://stackoverflow.com/a/53839983
    var customFabButton;
    if (_selectedTab == 0) {
~~~ SNIP ~~~

Вкладка по умолчанию - вкладка «Заметки» , который работает отлично. «Другая» вкладка - вот где проблема.

class NotePageScreen extends StatefulWidget {
  NotePageScreen();

  @override
  NotePageScreenState createState() => NotePageScreenState();
}

class NotePageScreenState extends State<NotePageScreen> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  List<Note> noteList;
  int count = 0;

  @override
  Widget build(BuildContext context) {
    Provider.of<NotesProvider>(context, listen: false).getAllDecryptedNotes();
    return Scaffold(
        key: _scaffoldKey,
        body: Provider.of<NotesProvider>(context, listen:false).decrypted
            ? NotePage()
            : Container(
                child: Center(
                  child: Text("Add a new Note"),
                ),
              ));
  }
}

Что здесь происходит

Я получаю расшифрованные заметки из базы данных. NoteProvider.dart:

class NotesProvider with ChangeNotifier {
  DatabaseHelper _databaseHelper = DatabaseHelper();
  List<Note> _noteList, decryptedNoteList;
  int _count = 0;
  bool _notesDecrypted = false;

  UnmodifiableListView<Note> get allNotes => UnmodifiableListView(_noteList);

  getNotes() async {
    await _databaseHelper.initializeDatabase();
    List<Note> noteList = await _databaseHelper.getNoteList();
    this._noteList = noteList;
    this._count = noteList.length;
    notifyListeners();
  }

UnmodifiableListView<Note> get allDecryptedNotes =>
      UnmodifiableListView(decryptedNoteList);
  getAllDecryptedNotes() async {
    List<Note> decryptedNoteList = [];
    for (var note in this._noteList) {
      decryptedNoteList.add(await decryptNote(note));
    }
    this.decryptedNoteList = decryptedNoteList;
    this._notesDecrypted = true;
    notifyListeners();
  }

  int get count => _count;
  bool get decrypted => _notesDecrypted;
~~~~ SNIP ~~~~

В чем здесь проблема

Итак, в первый раз нет никаких дешифрованных данных, но когда я читаю вкладки и снова возвращаюсь к ' Еще одна 'вкладка, там есть расшифрованные заметки.

Что я пробовал:

Если я установлю listen в True на либо из них:

Provider.of<NotesProvider>(context, listen: false).getAllDecryptedNotes();
Provider.of<NotesProvider>(context, listen: false).decrypted

затем страница загружается с первой попытки, но затем рекурсивно продолжает рендеринг.

Вот где ошибка.

Спасибо: )

Обновление - Добавление репо

Репо: https://github.com/LuD1161/notes_app/ Ветвь: reusable_components

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...