JHHK

欢迎来到我的个人网站
行者常至 为者常成

状态管理️

目录

InheritedWidget

一、介绍

7.2 数据共享(InheritedWidget)

InheritedWidget提供了一种在 widget 树中 从上到下共享数据的方式。
Flutter SDK中正是通过 InheritedWidget 来共享应用主题(Theme)和 Locale (当前语言环境)信息的。

我们创建一个继承自InheritedWidget 的 ShareDataWidget

class ShareDataWidget extends InheritedWidget {
  const ShareDataWidget({
    Key? key,
    required this.data,
    required Widget child,
  }) : super(key: key, child: child);

  final int data; //需要在子树中共享的数据,保存点击次数

  //定义一个便捷方法,方便子树中的widget获取共享数据
  static ShareDataWidget? of(BuildContext context) {

    // context 实际是 element,通过当前element节点从element树中可以找到ShareDataWidget对用的element节点
    // element持有Widget,就会找到ShareDataWidget
    // 同时还会进行注册依赖关系,所以当data数据变化时,调用ShareDataChildWidget的didChangeDependencies()
    return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();


    // 如果只想引用ShareDataWidget数据,不希望在ShareDataWidget的data发生变化时调用ShareDataChildWidget的didChangeDependencies()方法使用下面的方法
    // 该方法与上边的方法相比,不会进行关系注册
    // return context.getElementForInheritedWidgetOfExactType<ShareDataWidget>()!.widget as ShareDataWidget;
  }


  //该回调决定当data发生变化时,是否通知子树中依赖data的Widget重新build
  @override
  bool updateShouldNotify(ShareDataWidget old) {
    return old.data != data;
  }
}

我们再创建一个使用了共享数据的 ShareDataChildWidget


class ShareDataChildWidget extends StatefulWidget {
  ShareDataChildWidget({Key? key}):super(key: key);
  
  @override
  State createState() => _ShareDataChildWidgetState();
}


class _ShareDataChildWidgetState extends State<ShareDataChildWidget> {
  
  @override
  Widget build(BuildContext context) {
    // return Text("text");
    
    //使用InheritedWidget中的共享数据
    return Text(ShareDataWidget.of(context)!.data.toString());
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    //父或祖先widget中的InheritedWidget改变(updateShouldNotify返回true)时会被调用。
    //如果build中没有依赖InheritedWidget,则此回调不会被调用。
    print("Dependencies change ${widget.key}");
  }
}

二、应该在didChangeDependencies()中做什么?

一般来说子 widget 很少会重写此方法,因为在依赖改变后 Flutter 框架也都会调用build()方法重新构建组件树。
但是,如果你需要在依赖改变后执行一些昂贵的操作,比如网络请求,这时最好的方式就是在此方法中执行, 这样可以避免每次build()都执行这些昂贵操作。
也可以在data改变后不调用setState,避免build的调用,需要的逻辑在 didChangeDependencies 中进行,根据具体情况具体分析。


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.