Flutter Statefulwidget:在外部更新状态时如何重建小部件

发布于 2025-01-18 00:16:09 字数 1508 浏览 0 评论 0原文

我正在遇到一个问题,即在扑朔迷离中更新 statefulwidget 中的变量。具体来说,我有一个自定义窗口小部件 customErrorformfield ,它扩展了 statefulwidget 。该小部件包含一个方法 setErlorlist 来更新列表变量 errorList 。但是,当 setErrorlist 从另一个类调用时, build 方法 customErrorformfield 并不能反映更新的 errorlist

我了解到 setstate 应该触发小部件的重建,但是我不确定如何在 statefulwidget 中适当调用 setState 从外部类更新。这是相关的代码段,以更好地理解:

class CustomErrorFormField extends StatefulWidget {
  // Variable declaration
  List<String> errorList = [];

  // Method to update errorList
  void setErrorList(List<String> listOfError) {
    errorList = listOfError;
  }

  @override
  _CustomErrorFormFieldState createState() => _CustomErrorFormFieldState();
}

class _CustomErrorFormFieldState extends State<CustomErrorFormField> {
  @override
  Widget build(BuildContext context) {
    // Trying to print updated errorList, but not reflecting changes
    print(widget.errorList); 
    return ... // UI Code
  }
}

在另一类中,我正在更新错误列表这样:

// Instance creation and update
CustomErrorFormField nameTextFild = CustomErrorFormField(...);

// Inside some method
setState(() {
  // Updating errorList using setErrorList method
  if (condition) {
    nameTextFild.setErrorList([...]);
  } else {
    nameTextFild.setErrorList([...]);
  }
});

I'm encountering an issue with updating a variable within a StatefulWidget in Flutter. Specifically, I have a custom widget CustomErrorFormField which extends StatefulWidget. This widget contains a method setErrorList to update a list variable errorList. However, when setErrorList is called from another class, the build method in CustomErrorFormField does not reflect the updated errorList.

I understand that calling setState should trigger a rebuild of the widget, but I am unsure how to appropriately invoke setState in the StatefulWidget when the variable is updated from an external class. Here's the relevant code snippet for better understanding:

class CustomErrorFormField extends StatefulWidget {
  // Variable declaration
  List<String> errorList = [];

  // Method to update errorList
  void setErrorList(List<String> listOfError) {
    errorList = listOfError;
  }

  @override
  _CustomErrorFormFieldState createState() => _CustomErrorFormFieldState();
}

class _CustomErrorFormFieldState extends State<CustomErrorFormField> {
  @override
  Widget build(BuildContext context) {
    // Trying to print updated errorList, but not reflecting changes
    print(widget.errorList); 
    return ... // UI Code
  }
}

In another class, I'm updating the errorList like this:

// Instance creation and update
CustomErrorFormField nameTextFild = CustomErrorFormField(...);

// Inside some method
setState(() {
  // Updating errorList using setErrorList method
  if (condition) {
    nameTextFild.setErrorList([...]);
  } else {
    nameTextFild.setErrorList([...]);
  }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

燃情 2025-01-25 00:16:09

建议您从小部件外部更改小部件的状态。

您应该做的是将验证逻辑作为函数传递,并让小部件处理状态更改。

CustomFormField:

import 'package:flutter/material.dart';

class CustomErrorFormField extends StatefulWidget {
  //Take the validation logic as a parameter.
  final List<String> Function(String value) validator;
  const CustomErrorFormField({required this.validator});

  @override
  _CustomErrorFormFieldState createState() {
    return _CustomErrorFormFieldState();
  }
}

class _CustomErrorFormFieldState extends State<CustomErrorFormField> {
  
  //Keep the state inside the widget itself
  List<String> errorList = [];

  //Update the state from inside the widget
  void setErrorList(List<String> listOfError) {
    setState(() {
      errorList = listOfError;
    });
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      child: TextFormField(
        validator: (String value){
           //Use the validation logic to decide the error.
           setErrorList(widget.validator(value))
          }
        }
      ),
    );
  }
}

我使用TextFormField作为示例,您可以使用任何在更改时接受回调的小部件。

如果您从头开始制作所有内容,则可以将验证器函数附加到文本更改时触发的回调函数。通常这是在控制器的帮助下完成的。

用法:

final nameTextFild = CustomErrorFormField(
  key: ValueKey(count),
  labelName: "Name",
  iContext: context,
  validator: (String value) {
    if (!value.contains(RegExp(r'[0-9]'))) {
      return [];
    } else {
      return ["Invalid characters, use letters only."];
    }
  },
);

It's not recommended that you change the state of a widget from outside the widget.

What you should do instead is pass the validation logic as a function and let the widget handle the state change.

CustomFormField:

import 'package:flutter/material.dart';

class CustomErrorFormField extends StatefulWidget {
  //Take the validation logic as a parameter.
  final List<String> Function(String value) validator;
  const CustomErrorFormField({required this.validator});

  @override
  _CustomErrorFormFieldState createState() {
    return _CustomErrorFormFieldState();
  }
}

class _CustomErrorFormFieldState extends State<CustomErrorFormField> {
  
  //Keep the state inside the widget itself
  List<String> errorList = [];

  //Update the state from inside the widget
  void setErrorList(List<String> listOfError) {
    setState(() {
      errorList = listOfError;
    });
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      child: TextFormField(
        validator: (String value){
           //Use the validation logic to decide the error.
           setErrorList(widget.validator(value))
          }
        }
      ),
    );
  }
}

I have used TextFormField as an example, you can use any widget that accepts a callback upon change.

If you're making everything from scratch you can attach the validator function to a callback that fires when the text is changed. Usually this is done with the help of a controller.

usage:

final nameTextFild = CustomErrorFormField(
  key: ValueKey(count),
  labelName: "Name",
  iContext: context,
  validator: (String value) {
    if (!value.contains(RegExp(r'[0-9]'))) {
      return [];
    } else {
      return ["Invalid characters, use letters only."];
    }
  },
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文