简体   繁体   中英

Flutter Dart setState not working: Unhandled Exception: setState() called in constructor: ...(lifecycle state: created, no widget, not mounted)

I am new to dart / flutter. I am changing the default app created by flutter create command. This is the code (I want to show information from EventSource):

import 'dart:async';
import 'package:w3c_event_source/event_source.dart';
import 'package:flutter/material.dart';
import 'blocs/main_bloc.dart';

void main() async {
    runApp(MyApp());
    final events = EventSource(Uri.parse("https://example.com/broadcast/"));
    final subscription = events.events.listen((MessageEvent message) {
      var myhomepagestate = MyHomePageState();
      myhomepagestate.eventsource_message = '${message.data}';
      //print('${message.data}');
    });  
  
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'EXAMPLE',
      home: MyHomePage(title: 'EXAMPLE'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class MyHomePageState extends State<MyHomePage> {
  var _myeventsource = "";
  
  void set eventsource_message(message) {
    //if (!mounted) return;
    setState(() {
      _myeventsource = message;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'EventSource:',
            ),
            Text(
              '$_myeventsource',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

The error is at this command:

setState(() {
  _myeventsource = message;
});

The error is: Unhandled Exception: setState() called in constructor: MyHomePageState#8034c(lifecycle state: created, no widget, not mounted)

I have searching for one day and can't find the solution. Can anybody give a hint what I should look into? Can I just name the element, then change the element directly like HTML DOM?

Thanks.

You are instantiating a MyHomePageState widget that you will never need to do. Instead, you have to instantiate the MyHomePage. It does not work in this context though because MyHomePage is still not mounted anywhere. You are just instantiating it and trying to set the value.

Remove this part from the main method:

final events = EventSource(Uri.parse("https://example.com/broadcast/"));
final subscription = events.events.listen((MessageEvent message) {
  var myhomepagestate = MyHomePageState();
  myhomepagestate.eventsource_message = '${message.data}';
  //print('${message.data}');
});

Modify your MyHomePageState like this (Add initState and dispose methods. They are like constructors and destructors):

class MyHomePageState extends State<MyHomePage> {
  String _myeventsource = "";
  
  /**
  void set eventsource_message(message) {
    //if (!mounted) return;
    setState(() {
      _myeventsource = message;
    });
  }
  **/
 
 // Init state is called once when the widget is mounted. It's more like a constructor for your stateful widget which gets called by flutter itself when the widget is mounted.
 // You don't need to call this method explicitly.
 // Note that it won't be called again on hot reload. Refer to the documentation for more about it
 @override
 void initState() {
     super.initState();
     final events = EventSource(Uri.parse("https://example.com/broadcast/"));
     events.events.listen((MessageEvent message) {
         setState(() => _myeventsource = message.data);
     }
 }
 
 // And this method is like a destructor.
 // Called automatically by flutter when this widget is removed.
 @override
 void dispose() {
     // Remember to remove the listeners here
     super.dispose();
 }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'EventSource:',
            ),
            Text(
              '$_myeventsource',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM