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

Flutter本地状态变量_jobApplicationState更新后页面不刷新问题

本地状态变量无法实时更新的Flutter问题与解决办法

问题描述

Flutter项目中,本地状态变量_jobApplicationState无法实时更新:数据库中的值已经更新,但页面不会同步刷新显示,只有离开当前记录页面后再返回,内容才会正常展示。该功能由点击「Send inquiry」按钮触发,此前功能曾短暂正常运行但未保存代码。

问题代码

class JobApplicationView extends Stateful Widget {
  const JobApplicationView({Key? key}) : super(key: key);

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

class _JobApplicationViewState extends State<JobApplicationView> {
  CloudJobApplication? _jobApplication;
  final _formKey = GlobalKey<FormState>();
  final currentUser = AuthService.firebase().currentUser!;
  late final FirebaseCloudStorage _firebaseService;
  late String _jobApplicationState;
  late DateTime _jobApplicationStartDate;
  late DateTime _jobApplicationEndDate;
  bool? isJobCreatorSameAsJobApplicator;
  String? _jobCreatorId;
  String? _jobApplicatorId;
  String? _jobDescription;
  List? _jobUserData;
  String? _jobAddress;
  String? _jobType;

  @override
  void initState() {
    super.initState();
    _jobApplicationStartDate = DateTime.now();
    _jobApplicationEndDate = DateTime.now();

    _firebaseService = FirebaseCloudStorage();
  }

  createOrGetExistingJob(BuildContext context) async {
    final widgetJobApplication = context.getArgument<CloudJobApplication>();

    if (widgetJobApplication != null) {
      _jobApplication = widgetJobApplication;
      _jobApplicationState = widgetJobApplication.jobApplicationState;
      _jobApplicatorId = widgetJobApplication.jobApplicatorId;
      _jobCreatorId = widgetJobApplication.jobCreatorId;
      _jobDescription = widgetJobApplication.jobApplicationDescription;

      return widgetJobApplication;
    }
    print('ELSE TRIGGERED!');
    return widgetJobApplication;
  }

  void _updateJobField(localStateField, jobColumn, jobColumnValue) async {
    setState(() {
      if (localStateField == '_jobApplicationState') {
        _jobApplicationState = jobColumnValue;
      }
    });

    await _firebaseService.updateJobApplicationColumn(
      documentId: _jobApplication?.documentId as String,
      fieldNameColumn: jobColumn,
      fieldNameColumnValue: jobColumnValue,
    );
  }

  sendInqury() {
    print('setting job applications state!');
    print('_jobApplicationState b4:: $_jobApplicationState');

    _updateJobField(_jobApplicationState, jobApplicationStateColumn,
        jobApplicationStateOpen);
    print('_jobApplicationState after:: $_jobApplicationState');
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('update job application'),
        actions: [],
      ),
      body: FutureBuilder(
        future: createOrGetExistingJob(context),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.done:
              return Form(
                key: _formKey,
                child: ListView(
                  padding: const EdgeInsets.all(32.0),
                  children: [
                    const Divider(
                      height: 20,
                      thickness: 5,
                      indent: 0,
                      endIndent: 0,
                      color: Colors.blue,
                    ),
                    Text(_jobApplicationState),
                    TextButton(
                      style: TextButton.styleFrom(
                        foregroundColor: Colors.white,
                        backgroundColor: Colors.blue,
                        padding: const EdgeInsets.all(16.0),
                        textStyle: const TextStyle(fontSize: 20),
                      ),
                      onPressed: sendInqury,
                      child: const Text('Send inquiry'),
                    )
                  ],
                ),
              );

            default:
              return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

解决方案与修正代码

核心修正点

  • 移除间接更新状态的_updateJobField方法,直接在按钮点击回调中调用setState更新本地状态,避免传递字段名导致的逻辑错误
  • 给_jobApplicationState设置初始默认值,替换late声明,规避未初始化的潜在问题
  • 优化数据获取逻辑,区分首次加载和后续更新的数据源,确保本地状态与页面展示一致

修正后的代码

import 'dart:developer';
import 'package:flutter/material.dart';
import '../../services/cloud/cloud_job_application.dart';
import '/services/auth/auth_service.dart';
import '/utilities/generics/get_arguments.dart';
import '/services/cloud/firebase_cloud_storage.dart';

class JobApplicationView extends Stateful Widget {
  const JobApplicationView({Key? key}) : super(key: key);

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

class _JobApplicationViewState extends State<JobApplicationView> {
  CloudJobApplication? _jobApplication;
  late final FirebaseCloudStorage cloudFunctions;
  final _formKey = GlobalKey<FormState>();
  final currentUser = AuthService.firebase().currentUser!;
  // 状态变量
  String _jobApplicationState = 'default';
  String _jobApplicationSubState = 'default';
  late final TextEditingController _jobDescriptionController;

  @override
  void initState() {
    super.initState();
    cloudFunctions = FirebaseCloudStorage();
    _jobDescriptionController = TextEditingController();
  }

  getExistingJobApplication(BuildContext context) async {
    log('getExistingJobApplication()');

    if (_jobApplicationState == 'default') {
      var widgetJobApplication = context.getArgument<CloudJobApplication>();

      log('首次打开职位申请,返回服务器数据');
      _jobApplication = widgetJobApplication;
      _jobApplicationState =
          widgetJobApplication?.jobApplicationState as String;
      _jobDescriptionController.text =
          widgetJobApplication?.jobApplicationDescription as String;
      return widgetJobApplication;
    } else {
      log('职位申请已更新,返回本地数据');
      return cloudFunctions.getJobApplication(_jobApplication!.documentId);
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('update job application'),
        actions: [],
      ),
      body: FutureBuilder(
        future: getExistingJobApplication(context),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.done:
              return Form(
                key: _formKey,
                child: ListView(padding: const EdgeInsets.all(32.0), children: [
                  Text(_jobApplicationState),
                  Text(_jobDescriptionController.text),
                  const Divider(
                    height: 20,
                    thickness: 5,
                    indent: 0,
                    endIndent: 0,
                    color: Colors.blue,
                  ),

                  TextFormField(
                    controller: _jobDescriptionController,
                    maxLines: 5,
                    decoration: InputDecoration(
                      hintText: "The toilet wont flush",
                      filled: true,
                      label: Container(
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(16.0),
                          color: Colors.white,
                        ),
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: const [
                            Padding(padding: EdgeInsets.only(left: 8.0)),
                            Icon(Icons.info_outline),
                            Padding(
                              padding: EdgeInsets.only(left: 8.0, right: 8.0),
                              child: Text("Job description"),
                            ),
                          ],
                        ),
                      ),
                    ),
                    validator: (str) =>
                        str == '' ? "Job description can't be empty" : null,
                  ),
                  TextButton(
                      onPressed: () async {
                        setState(() {
                          _jobApplicationState = 'Open';
                        });
                        await cloudFunctions.updateJobApplication(
                          documentId: _jobApplication?.documentId as String,
                          jobDescription: _jobDescriptionController.text,
                          jobApplicationState: 'Open',
                        );
                      },
                      child: const Text('update state')),
                ]),
              );

            default:
              return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:40:20