Widgets are accidentally sharing state???

I’m building a simple app, but I’ve run into a problem that doesn’t make any sense, and I can’t figure out why it’s happening. Whenever I place two stateful widgets in a list together, one after another, they seem to share the exact same state, and the widget doesn’t even change at all, it just stays the same state. I can’t figure out how to turn off this functionality. I’ve build just a simple demo to show exactly what’s happening:

import 'dart:math';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const MyHomePage(),
    );
  }
}

class RandomNumberClass extends StatefulWidget {
  const RandomNumberClass({super.key});

  @override
  State<RandomNumberClass> createState() => _RandomNumberClassState();
}

class _RandomNumberClassState extends State<RandomNumberClass> {
  int randomInt = 1 + Random().nextInt(100);

  @override
  Widget build(BuildContext context) {
    return Text(randomInt.toString());
  }
}


class RandomNumberClass2 extends StatefulWidget {
  const RandomNumberClass2({super.key});

  @override
  State<RandomNumberClass2> createState() => _RandomNumberClass2State();
}

class _RandomNumberClass2State extends State<RandomNumberClass2> {
  int randomInt = 1 + Random().nextInt(100);

  @override
  Widget build(BuildContext context) {
    return Text(randomInt.toString());
  }
}


// If I set it up like this, the random number will be generated only once
class AppData {
  static final List<Widget> widgets = [
    RandomNumberClass(), // All of these will have the same number
    RandomNumberClass(),
    RandomNumberClass(),
  ];
}

// If I set it up like this, the random number will be generated every time
class AppData2 {
  static final List<Widget> widgets = [
    RandomNumberClass(),
    RandomNumberClass2(),
    RandomNumberClass(),
    RandomNumberClass2(),
    RandomNumberClass(), // But then at the end it repeats the same number
    // because the widget at the end is the same as the one at the beginning
  ];
}



class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Text('The value of the counter:'),
          Text('$_counter'),
          const Text('The random number in the widget:'),
          AppData.widgets[_counter],
        ],
      )),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _counter = (_counter + 1) % AppData.widgets.length;
          });
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

Why are you recreating the Random() instance over and over again rapidly. That could likely interfere with good seed selection.

Instead, create the Random() instance once at the top of your program, and use the instance everywhere. You should see very different results in your app.

I don’t think the issue is the use of Random. Its this line:

AppData.widgets[_counter]

and not using keys.

Remember widgets are just configuration. You are using the same widget type without keys, so flutter will reuse the state and call didUpdateWidget on the state class.

If you want to recreate the state each time, use different keys for each widget.

2 Likes

Thanks for the simple answer! I had no idea about keys