skip to Main Content

After clicking the button to update _formData, why does the page not display the new value?

import 'package:flutter/material.dart';

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

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

class _TestPageState extends State<TestPage> {
  Map<String, String> _formData = { 
    'id': '',
    'title': '',
    'desc': '',
  };
  @override
  Widget build(BuildContext context) {
    return Container(
        child: Column(
      children: [
        FilledButton(
            onPressed: () {
              setState(() {
                _formData['title'] = _getText();
              });
            },
            child: Text('test')),
        TextFormField(
          decoration: const InputDecoration(labelText: 'Title'),
          initialValue: _formData['title'],
          onSaved: (val) => _formData['title'] = val!,
        ),
        TextFormField(
          decoration: const InputDecoration(labelText: 'Description'),
          initialValue: _formData['desc'],
          onSaved: (val) => _formData['desc'] = val!,
        ),
      ],
    ));
  }
}

String _getText() {
  return DateTime.now().toString();
}

I need to fill in the selected product information into this form, there are about 20 fields, so I hope to use setData instead of the controller.

2

Answers


  1. some changes in code, try below code :

    class DemoScreen extends StatefulWidget {
      const DemoScreen({super.key});
    
      @override
      State<DemoScreen> createState() => _DemoScreenState();
    }
    
    class _DemoScreenState extends State<DemoScreen> {
      final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); // Add this key
    
      Map<String, String> _formData = {
        'id': '',
        'title': '',
        'desc': '',
      };
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Form(
            key: _formKey, // Assign the form key
            child: Column(
              children: [
                FilledButton(
                  onPressed: () {
                    setState(() {
                      _formData['title'] = _getText();
                    });
                  },
                  child: Text('test'),
                ),
                TextFormField(
                  decoration: const InputDecoration(labelText: 'Title'),
                  initialValue: _formData['title'],
                  onSaved: (val) => _formData['title'] = val!,
                ),
                TextFormField(
                  decoration: const InputDecoration(labelText: 'Description'),
                  initialValue: _formData['desc'],
                  onSaved: (val) => _formData['desc'] = val!,
                ),
                ElevatedButton(
                  onPressed: () {
                    _saveFormData();
                  },
                  child: Text('Save'),
                ),
              ],
            ),
          ),
        );
      }
    
      void _saveFormData() {
        if (_formKey.currentState!.validate()) {
          _formKey.currentState!.save();
          debugPrint("_formData-----------$_formData");
        }
      }
    
      String _getText() {
        return DateTime.now().toString();
      }
    }
    
    Login or Signup to reply.
  2. it seems like that TextFormField will not be updated after you call setState(), use _formData['title'] as a key of TextFormField like below

              TextFormField(
                key: Key(_formData['title'] ?? ''),
                decoration: const InputDecoration(labelText: 'Title'),
                initialValue: _formData['title'],
                onSaved: (val) => _formData['title'] = val!,
              ),
    
    

    then TextFormField will be updated every time you update _formData['title']

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search