ITADN

Recreating a value does not cause a rebuild

#21Closedclragon 创建于 2025-03-19
bug
C
clragoncommented
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 条评论