skip to Main Content

I wrote a simple dart program to test pass of int

a(int x) {
  x++;
  print(x);
}

main() {
  int x = 1;
  a(x);
  print(x);
}

Output:

2
1

Which means there are 2 separate int, after pass they don’t effect each other.


But in the following flutter program, seems state’s int variable effect widget’s int variable after pass via constructor.

import 'package:flutter/material.dart';

class CounterDisplay extends StatelessWidget {
  const CounterDisplay({required this.count, super.key});

  final int count;

  @override
  Widget build(BuildContext context) {
    return Text('Count: $count');
  }
}

class CounterIncrementor extends StatelessWidget {
  const CounterIncrementor({required this.onPressed, super.key});

  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      child: const Text('Increment'),
    );
  }
}

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

  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _counter = 0;

  void _increment() {
    setState(() {
      ++_counter;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        CounterIncrementor(onPressed: _increment),
        const SizedBox(width: 16),
        CounterDisplay(count: _counter),
      ],
    );
  }
}

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: Center(
          child: Counter(),
        ),
      ),
    ),
  );
}

Above code is from https://docs.flutter.dev/ui#changing-widgets-in-response-to-input, the 2nd part.

Since CounterDisplay(count: _counter) pass an int to constructor. I thought after pass, there should be 2 separate int, why would the change of _counter from _CounterState effect count from CounterDisplay ?

3

Answers


  1. When the parent widget rebuilds because of the setState, the child widget is also rebuilt, because its parameter has changed. This is expected, and useful.

    Login or Signup to reply.
  2. In Dart, when you pass a value to a function, like this:

    void a(int x) {
      x++;
      print(x);
    }
    
    void main() {
      int x = 1;
      a(x);
      print(x);
    }
    

    The value of x in main does not change because integers are passed by value in Dart. To change the value in main, you need to create an increment function and pass that function into a. This way, the value of x in main will change, and you will get the updated value everywhere.

    void main() {
      int x = 1;
    
      // Define an increment function
      void increment() {
        x++; // Increment x
      }
    
      print('Before increment' + x.toString());
      a(increment);
      print('After increment' + x.toString());
    }
    
    void a(Function incrementFunction) {
      incrementFunction();
      print(
          'Inside a: After incrementing, value is incremented.');
    }
    

    In Flutter, if you need to change a value in a function, you have to modify the code as here

    import 'package:flutter/material.dart';
    
    class CounterDisplay extends StatefulWidget {
      const CounterDisplay({super.key});
    
      @override
      _CounterDisplayState createState() => _CounterDisplayState();
    }
    
    class _CounterDisplayState extends State<CounterDisplay> {
      int count = 0;
    
      @override
      Widget build(BuildContext context) {
        count++;
    
        return Text('Count: $count');
      }
    }
    

    To properly manage the counter in Flutter, you should use a stateful widget or a state management solution to update the value

    Login or Signup to reply.
  3. The reason: the _counter value from _CounterState affects the count value in CounterDisplay is related to how Flutter’s widget tree and state management work, rather than how primitive types (like int) are passed in Dart.

    • The int itself is still passed by value, but Flutter’s setState() causes the widget tree to rebuild.
    • The rebuilding process re-evaluates the value of _counter and passes the updated value to the CounterDisplay widget.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search