0

I'd like to reuse one function to update different state variables of a StatefulWidget. Which state variable gets updated should depend on the variable reference which is passed to the function as a parameter. Here's some example code:

class _MyScreenState extends State<MyScreen> {
  String stateVariable = 'initial value';

  void update(String variableRef) {
    setState((() {
      variableRef = 'updated value';
    })
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => update(stateVariable),
      child: Text(stateVariable)
    )
  }
}

The state is set successfully in the setState function, but unfortunately the state change is not represented in the UI, i.e. the build function is not called again.

My expectation here would be that the stateVariable should be updated since I pass the variable to the update function by reference. Is this assumption false?

Do you know a way of passing a state variable by reference so that it can be updated idempotently by a function?

Peter
  • 1,110
  • 10
  • 25

2 Answers2

5

Yes, the assumptions if false. Dart cannot pass variables by reference, all parameters are passed by value. (Object values are actually object references, but that's a separate and unrelated use of the word "reference", and passing an object as a parameter does pass the object reference by value).

If you want to pass something that allows the callee to change the value of a variable, you should pass a "setter function":

void update(void setVariable(String value)) {
   setState(() {
     setVariable('updated value');
   });
}
...
   update((value) { stateVariable = value; });

There is no way to "tear off" a setter, so you have to write the function out.

lrn
  • 64,680
  • 7
  • 105
  • 121
0

I accepted the answer of Irn and would like to share my solution, which I ended up using.

Future<String> update() async {
  ... // Do some async stuff here.
  return Future.value('updated value');
}
...
update().then((value) => setState(() { stateVariable = value });

It removes the necessity of updating the state in the update function. This does not answer my question, but is a more elegant way I believe.

Peter
  • 1,110
  • 10
  • 25