在颤振中从父小部件调用 setState 不会更新状态

Posted

技术标签:

【中文标题】在颤振中从父小部件调用 setState 不会更新状态【英文标题】:calling setState from the parent widget in flutter does not update the state 【发布时间】:2021-11-12 09:55:49 【问题描述】:

父小部件

class _FamilyListPageState extends State<FamilyListPage> 
  String initialValue = 'Search Families';

  void eraseInitialValue()      <-------------- This function is passed down to the child widget
    setState(() 
      initialValue = '';
      print('Inside the set state');    <-------- This line gets executed.
    );
  

  @override
  Widget build(BuildContext context) 
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text('Search Families'),
          centerTitle: true,
        ),
        backgroundColor: StaticEntry.backColor,
        body: Center(
          child: FractionallySizedBox(
            widthFactor: 0.8,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SearchInput(   <----------------------------------------- Child Widget
                  initialValue: initialValue,
                  onTapHandler: eraseInitialValue,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  

子小部件

import 'package:flutter/material.dart';

class SearchInput extends StatelessWidget 
  final String initialValue;
  final Function onTapHandler;      <----------- Function from the parent widget is stored in here

  SearchInput(this.initialValue, this.onTapHandler);

  @override
  Widget build(BuildContext context) 
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListTile(
          leading: Icon(
            Icons.search,
            size: 40,
          ),
          title: Container(
            child: TextFormField(
              initialValue: initialValue,
              textAlign: TextAlign.center,
              style: TextStyle(
                  color: Colors.grey,
                  fontWeight: FontWeight.bold,
                  fontFamily: 'Poppins',
                  letterSpacing: 1),
              onTap: onTapHandler,         <--------------- This is where I have made a pointer at the function received from the parent widget to be executed when tapped.
            ),
          ),
        ),
      ),
    );
  

背景

我有一个包含 TextFormField 的子小部件。该 TextFormFieldinitialValue'Search Families'。我试图在用户点击该 TextFormField 时删除该初始值,以便用户可以在该 TextFormField 中键入他/她想要的内容,而无需自己手动删除它。

我做了什么

为了实现这一点,我将我的父小部件设为有状态小部件。我的父窗口小部件的状态有一个名为 initialValue 的实例变量,它保存值 'Search Families' 用于配置的 initialValue 属性TextFormField 在子小部件内。

然后我在父窗口小部件中定义了一个名为 eraseInitialValue 的方法,它通过调用 setStateinitialValue 实例变量的值重置为空字符串/strong>。

最后在子窗口小部件中,我在这个函数上给出了一个指针,以便 TextFormFieldonTap 属性执行声明的函数,该函数又应该更新状态应用程序。

问题

但是,'Search Families' 文本永远不会改变。

(我在 setState 中添加了一条打印语句,以查看持有 setState 的函数是否被执行。确实如此。但状态没有更新。)

有人可以帮我理解这段代码不起作用吗?谢谢。

【问题讨论】:

【参考方案1】:

SearchInput 类中的 onTapHandler() 代替 onTapHandler

【讨论】:

【参考方案2】:

您是否尝试过使用GestureDetector?请更新您的代码并提供反馈。

父小部件

class _FamilyListPageState extends State<FamilyListPage> 
  String initialValue = 'Search Families';

  void eraseInitialValue()      <-------------- This function is passed down to the child widget
    setState(() 
      initialValue = '';
      print('Inside the set state');    <-------- This line gets executed.
    );
  

  @override
  Widget build(BuildContext context) 
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text('Search Families'),
          centerTitle: true,
        ),
        backgroundColor: StaticEntry.backColor,
        body: Center(
          child: FractionallySizedBox(
            widthFactor: 0.8,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                GestureDetector(
                  onTap: ()  eraseInitialValue(); ,
                  child: SearchInput( <----------------------------------------- Child Widget
                    initialValue: initialValue,
                    //onTapHandler: eraseInitialValue,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  

子小部件

import 'package:flutter/material.dart';

class SearchInput extends StatelessWidget 
  final String initialValue;
  final Function onTapHandler;      <----------- Function from the parent widget is stored in here

  SearchInput(this.initialValue, this.onTapHandler);

  @override
  Widget build(BuildContext context) 
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ListTile(
          leading: Icon(
            Icons.search,
            size: 40,
          ),
          title: Container(
            GestureDetector(
              onTap: ()  onTapHandler(); ,
              child: TextFormField(
                initialValue: initialValue,
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Colors.grey,
                  fontWeight: FontWeight.bold,
                  fontFamily: 'Poppins',
                  letterSpacing: 1),
              ),
            ),
          ),
        ),
      ),
    );
  

【讨论】:

我试过这个。但结果还是一样。我还尝试用GestureDetector 包装父小部件并从那里调用eraseInitialValue 函数。但还是没有运气..... 创建一个简单的类来执行print("It worked so far");onTap 方法中调用这个函数,看看它是否至少是打印 我试过你说的。打印"It works so far works!"。即使在我拥有的类(不是我们现在创建的测试类)中,当我在该函数中添加一个打印语句时,在点击子小部件时,该打印函数也会被执行。只是状态没有更新! 有人回答这个问题吗?我有类似的问题:***.com/questions/70235200/…

以上是关于在颤振中从父小部件调用 setState 不会更新状态的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中从父小部件访问所有孩子的状态?

Flutter - 无法从父小部件更改子状态

在 dispose() 之后调用 setState()

我的有状态小部件不会更新 ui,即使我正在调用 setState 并将正确的值传递给小部件类

异步功能完成后颤振 setState()

调用 setState 时,我的有状态小部件不会更新其状态