InheritedWidget的updateShouldNotify是否必要?求子widget不重建示例
InheritedWidget的updateShouldNotify生效示例
首先要明确:你混淆了InheritedWidget的普通子节点和依赖它的继承widget的区别:
- InheritedWidget的普通子widget(直接写在它
child参数里的组件),确实会随InheritedWidget的重建而重建,因为它们是父子关系。 - 但那些通过
dependOnInheritedWidgetOfExactType(或旧版的inheritFromWidgetOfExactType)获取InheritedWidget数据的widget,属于依赖该InheritedWidget的组件,这类组件是否重建,才由updateShouldNotify的返回值决定。
下面是一个完整的示例,能清晰展示updateShouldNotify的作用:
import 'package:flutter/material.dart'; // 自定义InheritedWidget,持有一个count状态 class CountInherited extends InheritedWidget { final int count; final VoidCallback onIncrement; const CountInherited({ super.key, required this.count, required this.onIncrement, required super.child, }); // 供子widget获取实例的方法 static CountInherited? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<CountInherited>(); } @override bool updateShouldNotify(covariant CountInherited oldWidget) { // 只有当count变化时,才通知依赖的widget return oldWidget.count != count; } } // 依赖CountInherited的组件,会打印重建日志 class CountDisplay extends StatelessWidget { const CountDisplay({super.key}); @override Widget build(BuildContext context) { print("CountDisplay 重建了"); final inherited = CountInherited.of(context)!; return Text( "当前计数: ${inherited.count}", style: const TextStyle(fontSize: 20), ); } } // 普通子组件,不是通过依赖获取数据,会随InheritedWidget重建 class NormalChild extends StatelessWidget { const NormalChild({super.key}); @override Widget build(BuildContext context) { print("NormalChild 重建了"); return const Text("我是普通子组件"); } } void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { int _count = 0; int _otherValue = 0; // 这个值变化不会影响CountInherited的updateShouldNotify void _incrementCount() { setState(() { _count++; }); } void _changeOtherValue() { setState(() { _otherValue++; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text("updateShouldNotify 示例")), body: Center( child: CountInherited( count: _count, onIncrement: _incrementCount, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const CountDisplay(), // 依赖InheritedWidget的组件 const SizedBox(height: 20), const NormalChild(), // 普通子组件 const SizedBox(height: 20), ElevatedButton( onPressed: _incrementCount, child: const Text("增加计数"), ), const SizedBox(height: 10), ElevatedButton( onPressed: _changeOtherValue, child: const Text("修改无关值"), ), ], ), ), ), ), ); } }
示例运行效果:
点击修改无关值按钮:
- 由于
_otherValue变化触发setState,CountInherited会重建,但updateShouldNotify对比新旧count值相同,返回false。 - 控制台会打印
NormalChild 重建了(因为它是CountInherited的普通子节点),但不会打印CountDisplay 重建了,说明依赖的组件没有被通知重建。
- 由于
点击增加计数按钮:
_count变化触发setState,CountInherited重建,updateShouldNotify返回true。- 控制台会同时打印
NormalChild 重建了和CountDisplay 重建了,说明依赖的组件被通知重建。
这样就能清晰看到updateShouldNotify的作用:它控制的是依赖该InheritedWidget的组件是否收到通知并重建,而非InheritedWidget的所有子节点。
内容的提问来源于stack exchange,提问作者ximmyxiao
相关产品推荐
相关产品推荐

