You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发:用户输入仅热重载显示 提交按钮无响应问题

问题根因

代码存在3个核心问题,导致点击提交按钮后待办区不更新,仅热重载后才显示内容:

  • 状态作用域错误:_textController、userInput、toDoList全部定义为全局变量,点击按钮时仅调用了LandingPage组件的setState,该方法只会触发LandingPage自身的重绘,独立的ToDos组件不会收到刷新通知,只有热重载触发全量应用刷新时才会读取到更新后的变量值。
  • 子组件被常量修饰:代码中写的const ToDos()是编译期常量,创建后不会响应任何状态变化。
  • 渲染逻辑错误:两个dart文件存在循环导入问题;ToDos组件没有遍历待办列表渲染,仅固定展示单个全局userInput值,无法支持多条待办展示;TextEditingController没有做资源释放,长期运行会触发内存泄漏。
修复步骤
  1. 收拢状态到父组件:把输入控制器、待办列表全部移到_LandingPageState内部管理,删除所有零散的全局变量,删除to_do_section.dart中对landing_page.dart的导入,解决循环引用问题。
  2. 改造子组件传参:给ToDos组件新增必传的待办列表参数,移除ToDos实例前的const修饰符,父组件更新列表后自动触发子组件重绘。
  3. 补全交互逻辑:提交时增加空内容判断,提交成功后清空输入框;在父组件dispose生命周期中释放输入控制器;子组件中用列表组件遍历传入的待办数据做渲染。

修正后代码

landing_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_application_1/presentation/widgets/to_do_section.dart';
import 'package:flutter_application_1/responsive_layout.dart';

class LandingPage extends StatefulWidget {
  const LandingPage({Key? key}) : super(key: key);

  @override
  State<LandingPage> createState() => _LandingPageState();
}

class _LandingPageState extends State<LandingPage> {
  // 状态统一放在父组件管理
  final _textController = TextEditingController();
  final List<String> toDoList = [];

  @override
  void dispose() {
    // 销毁控制器避免内存泄漏
    _textController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Center(child: Text("To-Do-App")),
        backgroundColor: Colors.redAccent,
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            // 移除const,向子组件传递待办列表
            ToDos(todoList: toDoList),
            _buildToDoAddArea()
          ],
        ),
      ),
    );
  }

  Column _buildToDoAddArea() {
    return Column(
      children:  [
        Padding(
          padding: const EdgeInsets.only(top: 8.0, left: 20, right: 20, bottom: 20),
          child: TextField(
            controller: _textController,
            textAlign: TextAlign.center,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              hintText: "Add a new ToDo",
            ),
          ),
        ),
        MaterialButton(
          color: Colors.redAccent,
          onPressed: () {
            final inputContent = _textController.text.trim();
            // 空输入不添加
            if (inputContent.isEmpty) return;
            setState(() {
              toDoList.add(inputContent);
            });
            // 提交后清空输入框
            _textController.clear();
          },
          child: const Text("Add", style: TextStyle(color: Colors.white)),
        ),
      ],
    );
  }
}

to_do_section.dart

import 'package:flutter/material.dart';
import 'package:flutter_application_1/responsive_layout.dart';

class ToDos extends StatefulWidget {
  // 接收父组件传入的待办列表
  final List<String> todoList;
  const ToDos({Key? key, required this.todoList}) : super(key: key);

  @override
  State<ToDos> createState() => _ToDosState();
}

class _ToDosState extends State<ToDos> {
  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Padding(
      padding: EdgeInsets.only(
          top: SizeConfig.blockSizeHorizontal * 10,
          left: SizeConfig.blockSizeVertical * 2.5,
          right: SizeConfig.blockSizeVertical * 2.5,
          bottom: SizeConfig.screenHeight / 8
      ),
      child: SizedBox(
        width: SizeConfig.blockSizeHorizontal*100,
        height: SizeConfig.blockSizeVertical*40,
        child: Container(
          decoration: BoxDecoration(
              color: Colors.grey[400],
              borderRadius: BorderRadius.circular(30),
              border: Border.all(
                  color: Colors.black45, style: BorderStyle.solid, width: 4)),
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            // 遍历传入的待办列表渲染
            child: ListView.builder(
              itemCount: widget.todoList.length,
              itemBuilder: (context, index) {
                return Card(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(widget.todoList[index]),
                  ),
                );
              },
            )
          ),
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者laniakea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:39:38