Form

pharmDev·2024년 12월 15일

1. Form과 GlobalKey

Form

  • 역할: 여러 입력 필드를 그룹으로 묶어서 관리하는 컨테이너 위젯입니다.
    • 입력 필드들의 데이터를 한 번에 검증하거나 저장하는 데 사용됩니다.
  • 특징: Form 자체는 검증 및 저장 기능만 제공하며, 입력 필드(TextFormField 등)의 validator나 onSaved 메서드와 함께 사용됩니다.

사용 예시:

Form(
  key: formKey, // GlobalKey를 연결
  child: Column(
    children: [
      TextFormField(
        decoration: InputDecoration(labelText: 'Name'),
        validator: (val) => val == null || val.isEmpty ? 'Enter your name' : null,
        onSaved: (val) => print('Saved Name: $val'),
      ),
      ElevatedButton(
        onPressed: () {
          if (formKey.currentState!.validate()) { // 모든 입력 필드 검증
            formKey.currentState!.save(); // 모든 입력 필드의 onSaved 호출
          }
        },
        child: Text('Submit'),
      ),
    ],
  ),
)

GlobalKey

  • 역할: 특정 위젯(여기서는 Form)의 상태를 추적하고 조작할 수 있는 키입니다.
    • Form의 상태를 변경하거나 검증 결과를 확인하려면 GlobalKey<FormState>를 사용해야 합니다.

왜 필요한가?

  • Flutter에서 상태 관리 규칙상, 위젯 외부에서 Form의 상태를 직접 조작할 수 없습니다.
  • GlobalKey를 통해 외부에서 Form의 상태(currentState)에 접근할 수 있습니다.

사용법:

  1. GlobalKey 선언:

    final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  2. Form에 연결:

    Form(key: formKey, child: ...)
  3. 상태 접근:

    • 검증: formKey.currentState!.validate()
    • 저장: formKey.currentState!.save()

2. formKey

  • GlobalKey 객체로, Form 위젯을 조작하기 위한 도구입니다.
  • Form의 상태(currentState)에 접근하고 조작하기 위해 사용됩니다.

formKey.currentState의 주요 메서드:

  1. validate():
    • 폼에 포함된 모든 입력 필드의 validator를 호출합니다.
    • 하나라도 검증에 실패하면 false를 반환, 모두 통과하면 true 반환.
  2. save():
    • 폼에 포함된 모든 입력 필드의 onSaved 메서드를 호출합니다.

3. formKey.currentState!.validate()

  • 역할: 폼의 모든 입력 필드를 검증합니다.
  • 동작:
    1. 각 TextFormField의 validator를 호출.
    2. validator가 에러 메시지를 반환하면 입력 필드에 오류가 표시되고, false 반환.
    3. 모든 필드가 유효하면 true 반환.

예시:

if (formKey.currentState!.validate()) {
  print('모든 입력이 유효합니다.');
} else {
  print('입력이 잘못되었습니다.');
}

4. formKey.currentState!.save()

  • 역할: 폼의 모든 입력 필드 데이터를 저장합니다.
  • 동작:
    1. 각 TextFormField의 onSaved 메서드를 호출.
    2. 입력된 데이터를 지정된 변수나 로직으로 저장.

예시:

if (formKey.currentState!.validate()) {
  formKey.currentState!.save(); // 모든 입력 필드의 onSaved 실행
  print('데이터가 저장되었습니다.');
}

5. validator

  • 역할: 사용자의 입력값을 검증하고, 검증 실패 시 에러 메시지를 반환합니다.
  • 동작:
    • TextFormField에 입력된 값을 검증합니다.
    • 검증에 실패하면 반환된 에러 메시지가 해당 필드 아래에 표시됩니다.

예시:

validator: (val) {
  if (val == null || val.isEmpty) {
    return '이 필드를 입력하세요.';
  }
  if (val.length < 3) {
    return '최소 3글자 이상 입력하세요.';
  }
  return null; // 유효한 경우
},

6. onSaved

  • 역할: TextFormField에 입력된 값을 저장하는 로직을 정의합니다.
  • 동작:
    • save() 호출 시 실행됩니다.
    • 데이터가 유효할 경우 입력값을 변수로 저장하거나 특정 로직을 실행합니다.

예시:

onSaved: (val) {
  print('입력값이 저장되었습니다: $val');
},

7. 첨부 파일에서의 실제 사용 예

파일: schedule_bottom_sheet.dart

  • _Time 클래스에서 Form과 관련 메서드 사용:
class _Time extends StatelessWidget {
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();

  
  Widget build(BuildContext context) {
    return Form(
      key: formKey,
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                child: CustomTextField(
                  label: '시작 시간',
                  onSaved: (val) => print('시작 시간: $val'),
                  validator: (val) => val == null || val.isEmpty
                      ? '시작 시간을 입력하세요.'
                      : null,
                ),
              ),
              Expanded(
                child: CustomTextField(
                  label: '마감 시간',
                  onSaved: (val) => print('마감 시간: $val'),
                  validator: (val) => val == null || val.isEmpty
                      ? '마감 시간을 입력하세요.'
                      : null,
                ),
              ),
            ],
          ),
          ElevatedButton(
            onPressed: () {
              if (formKey.currentState!.validate()) {
                formKey.currentState!.save();
                print('폼 데이터 저장 완료');
              } else {
                print('폼 검증 실패');
              }
            },
            child: Text('SAVE'),
          ),
        ],
      ),
    );
  }
}

실행 흐름

  1. 버튼 클릭 시:
    • validate() 호출 → 모든 필드 검증.
    • 검증 성공 시 save() 호출 → 입력값 저장.
  2. 유효하지 않은 입력:
    • validator에서 에러 메시지 반환 → 필드 아래 표시.

마무리 요약

요소역할 및 사용 예시
Form입력 필드들을 그룹화하고, validate()와 save()를 통해 데이터를 관리.
GlobalKeyForm의 상태를 추적하고 조작하기 위한 키.
formKeyGlobalKey를 이용해 Form의 상태를 저장.
formKey.currentState!.validate()입력 필드들의 유효성을 확인. validator를 호출하여 검증.
formKey.currentState!.save()입력 필드들의 데이터를 저장. onSaved 호출.
validator입력 필드의 데이터를 검증하는 로직.
onSaved검증된 데이터를 저장하거나 처리하는 로직.

이제 각 요소가 어떻게 서로 연결되어 동작하는지 명확히 이해했길 바랍니다! 😊

profile
코딩을 배우는 초보

0개의 댓글