微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当父母的状态发生变化时,如何让子小部件更新?

如何解决当父母的状态发生变化时,如何让子小部件更新?

提前道歉发布伪代码。真正的代码会太长。

我有一个屏幕,顶部有一个下拉菜单用户可以在其中选择一个选项。页面的其余部分根据该选项进行更新。像这样:

// state variable
String idFromDropdown;

Column(
  children: [
    DropDownWidget(),ChildWidget1(myId: idFromDropDown),ChildWidget2(myId: idFromDropDown),ChildWidget3(myId: idFromDropDown),]
)

在子小部件中,我使用 widget.myId 传递到后端服务并读取新数据。

期望是当下拉列表发生变化时我调用

setState((val)=>{idFromDropdown = val});

然后该值将级联到三个子小部件中。以某种方式根据 widget.myId 的新值触发小部件重新连接到后端服务。

如何触发子小部件的状态更新?

我最终使用了 ValueNotifier。而不是直接使用字符串并将其传递给子小部件。我最终做了类似的事情:

ValueNotifier<String> idFromDropdown;
...
setState((val)=>{idFromDropdown.value = val});

然后在每个小部件中,我在传入的 ValueNotifier 上添加一个侦听器,并重新触发对后端服务的读取。

虽然这有效,但我觉得我遗漏了一些明显的东西。我的 childwidgets 现在接受一个 ValueNotifier 而不是一个值。恐怕这会让我的 ChildWidgets 在其他情况下更难使用。

这是正确的做法吗?

解决方法

使用提供程序包您的问题将轻松解决

,

这是 Riverpod 的示例。

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final fetureDataForChild =
    FutureProvider.family<List<String>,String>((ref,id) {
  return Future.delayed(Duration(seconds: 1),() {
    return <String>["active","${id}","got it "];
  });
});

class MainWidgetR extends StatefulWidget {
  @override
  _MainWidgetState createState() => _MainWidgetState();
}

class _MainWidgetState extends State<MainWidgetR> {
  String id = "id 0";

  final items = List.generate(
    4,(index) => DropdownMenuItem(
      child: Text("Company $index"),value: "id $index",),);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,children: [
            DropdownButton(
              items: items,value: id,onChanged: (value) {
                setState(() {
                  id = value as String;
                });
              },RiverPodRespone(
              id: id,],);
  }
}

class RiverPodRespone extends ConsumerWidget {
  final String id;
  RiverPodRespone({
    required this.id,});
  @override
  Widget build(BuildContext context,watch) {
    final futureData = watch(fetureDataForChild("$id"));

    return futureData.map(
      data: (value) {
        final items = value.value;

        return Column(
          children: [
            ...items.map((e) => Text("$e")).toList(),);
      },loading: (value) => CircularProgressIndicator(),error: (value) => Text(value.toString()),);
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。