Recreating a value does not cause a rebuild
bug
Given
```dart
TestRef.bind(
context,
() => value + 1,
key: [value],
);
```
I would expect that any build method that uses `TestRef.of` to be rebuilt when `value` changes and recreates the binding for `TestRef`.
When testing this however, I found that this is not the case.
This "bug" (most likely) makes the `key` property useless and leads to dangerous scenarios where widget trees use old values that were valid when they were first built, but no longer are now.
Oddly enough, this behaviour does work when using `bindValue`. The Readme explicitly mentions that `bindValue` does this.
However, it is unclear to me why this would be restricted. I cannot see any advantage to not updating our dependants when our origin value changes.
Attached is a reproducible:
<details>
<summary>Sample code</summary>
```dart
import 'dart:math';
import 'package:context_plus/context_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp(const App());
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return ContextPlus.root(
child: MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const First(),
),
);
}
}
// ignore: non_constant_identifier_names
final TestRef = Ref<int>();
class First extends StatefulWidget {
const First({super.key});
@override
State<First> createState() => _FirstState();
}
class _FirstState extends State<First> {
int value = 0;
Object built = Object();
@override
Widget build(BuildContext context) {
TestRef.bind(
context,
() {
built = Object();
return value + 1;
},
key: [value],
);
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text('Why No Rebuilds?'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Value: $value'),
Text('Built: ${shortHash(built)}'),
ElevatedButton(
onPressed: () => setState(() => value = Random().nextInt(100)),
child: const Text('Randomize'),
),
const Second(),
],
),
),
);
}
}
class Second extends StatelessWidget {
const Second({super.key});
@override
Widget build(BuildContext context) {
final value = TestRef.of(context);
return Text('Value: $value');
}
}
```
</details>
As well as a quick video:
https://github.com/user-attachments/assets/3c78f4dd-3948-433a-9873-7db48921ab1d
关闭于 2025-03-19 2 条评论