'setState() or markNeedsBuild() called during build. in Navigator Push

I want to use the setState of the randomWord class for the SaveWordScreen class in the following way, but the problem is setState() or markNeedsBuild() called during the build.

this is my code RandomWord.dart

class RandomWord extends StatefulWidget {
      @override
      _RandomWordState createState() => _RandomWordState();
    }
    
    class _RandomWordState extends State<RandomWord> {
      late bool _alreadySaved = false;
      var saveWords = [];
      String randomWord = WordPair.random().asString;
    
      void _changeWord() {
        // Merubah state setiap klik next
        setState(() {
          randomWord = WordPair.random().asString;
          _alreadySaved = isSaved(randomWord);
        });
      }
    
      _saveWords() {
        // Jika tidak di klik favorite
        if (isSaved(randomWord)) {
          saveWords.remove(randomWord);
    
          setState(() {
            _alreadySaved = isSaved(randomWord);
          });
    
          // Jika di klik favorite
        } else {
          saveWords.add(randomWord);
          print(saveWords);
    
          setState(() {
            _alreadySaved = isSaved(randomWord);
          });
    
          // halaman baru
          _newSavePage();
        }
      }
    
      void _newSavePage() {
        Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => SaveWordScreen(
                    saveWords: saveWords,
                    alreadySaved: _alreadySaved,
                    randomWord: randomWord,
                    saveWordsCallback: _saveWords(),
                  )),
        );
      }
    
      bool isSaved(String key) {
        return saveWords.contains(key);
      }

SaveWordScreeen.dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:random_word/randomWord.dart';

class SaveWordScreen extends StatefulWidget {
  // memindahkan data savewords dari kelas lain
  var saveWords = [];
  late bool alreadySaved;
  String randomWord;

  final _callback; // callback reference holder

  //you will pass the callback here in constructor
  SaveWordScreen(
      {required this.saveWords,
      required this.alreadySaved,
      required this.randomWord,
      required void saveWordsCallback()})
      : _callback = saveWordsCallback;

  // memindahkan data savewords dari kelas savewordscreen ke savewordscreenstate
  @override
  _SaveWordScreenState createState() => _SaveWordScreenState(
      saveWords: saveWords, alreadySaved: alreadySaved, randomWord: randomWord);
}

class _SaveWordScreenState extends State<SaveWordScreen> {
  // memindahkan data savewords dari kelas lain
  var saveWords = [];
  bool alreadySaved;
  String randomWord;

  _SaveWordScreenState(
      {required this.saveWords,
      required this.alreadySaved,
      required this.randomWord});

  bool isSaved(String key) {
    return saveWords.contains(key);
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build

    return Scaffold(
        appBar: AppBar(
          title: Text('Saved Words'),
        ),
        body: ListView.builder(
          itemCount: saveWords.length,
          itemBuilder: (BuildContext ctx, int index) {
            return Padding(
              padding: const EdgeInsets.all(8.0),
              child: Card(
                child: Padding(
                  padding: EdgeInsets.all(15.0),
                  child: Column(
                    children: [
                      ListTile(
                        title: Text(
                          saveWords[index],
                          style: GoogleFonts.poppins(
                            fontSize: 22,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        subtitle: Text("Click to save the word!"),
                        leading: IconButton(
                            onPressed: () {
                              widget._callback();
                            },
                            icon: Icon(
                              Icons.close,
                            )),
                      ),
                    ],
                  ),
                ),
              ),
            );
          },
        ));
  }
}

I think I'm wrong on newSavePage() method, please help me

error

The following assertion was thrown building Builder(dirty): setState() or markNeedsBuild() called during build.

This random word widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.



Solution 1:[1]

you are calling the function _saveWords while navigating, you need to pass the function as a reference not call it

change it to this

SaveWordScreen(
                saveWords: saveWords,
                alreadySaved: _alreadySaved,
                randomWord: randomWord,
                saveWordsCallback: _saveWords, // instead of _saveWords()
              )),

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 omar hatem