Lodea
Lodea

Reputation: 189

How to use stateful widget parameters in state class at construction without adding the widget to the tree?

I stumped into a problem where I need to use a StatefulWidget parameter in its state class when it's constructed, but I couldn't find a way to do it since using widget.[whatever variable name] in the state's class constructor returns an unexpected null value, and the initState function only runs when the widget is being drawn to the screen.

For example:

import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  final String text;
  Test(this.text);

  final state = _TestState();
  @override
  _TestState createState() => state;
}

class _TestState extends State<Test> {
  String? changingText;

  void updateChangingText(String moreText){
      changingText = changingText! + moreText;
  }

  @override
  void initState() {
    super.initState();

    changingText = widget.text;
  }

  @override
  Widget build(BuildContext context) {
    return Text(changingText!);
  }
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var w = Test('test');
    w.state.updateChangingText(' text');

    return MaterialApp(home: Scaffold(body: 
      Test('test text')
    ));

  }
}

void main() {
  runApp(App());
}

This doesn't work since changingText is being updated before initState gives it its initial value since it only runs when Text is being drawn to the screen and this:

import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  final String text;
  Test(this.text);

  final state = _TestState();
  @override
  _TestState createState() => state;
}

class _TestState extends State<Test> {
  String? changingText;

  void updateChangingText(String moreText){
      changingText = changingText! + moreText;
  }

  _TestState(){
    changingText = widget.text;
  }

  @override
  Widget build(BuildContext context) {
    return Text(changingText!);
  }
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var w = Test('test');
    w.state.updateChangingText(' text');

    return MaterialApp(home: Scaffold(body: 
      Test('test text')
    ));

  }
}

void main() {
  runApp(App());
}

doesn't work either since you can't use widget.[whatever] in state class constructors (for some reason).

So what can I do to use widget parameters in the state class before the widget is drawn to the screen?

Thanks in advance for the help

Upvotes: 1

Views: 2086

Answers (1)

Lucas Britto
Lucas Britto

Reputation: 375

You should use the initState method present in the State for this instead of the constructor

@override
void initState() {
  changingText = widget.text;
  super.initState();
}

Upvotes: 2

Related Questions