Flutter

[Flutter] Flutter에서 Key의 역할과 필요성

미로910 2024. 11. 14. 13:00

Flutter에서 Key의 역할과 필요성

Key는 Flutter 애플리케이션에서 위젯의 고유성을 보장하고, 상태를 관리하는 데 중요한 역할을 합니다. 특히, 위젯 트리에서 요소의 순서가 변경되거나 목록이 동적으로 업데이트될 때 Key는 의도하지 않은 UI 동작을 방지하는 핵심 요소입니다.

 

Key란 무엇인가?

  • Flutter는 모든 위젯마다 Element라는 객체를 내부적으로 생성해 트리를 만듭니다.
  • Flutter에서 Key는 각 위젯을 고유하게 식별하기 위한 속성입니다.
  • 복잡한 위젯 트리 구조에서 위치가 바뀌거나, 재구성될 때 위젯을 정확히 식별하는 데 중요한 역할을 합니다.

Key의 작동 방식

Flutter는 Key를 통해 위젯을 고유하게 식별합니다. 같은 타입이라도 Key가 다르면 Flutter는 이를 별개의 위젯으로 인식하고, 다른 상태를 유지하도록 처리합니다. 따라서 Key가 있는 위젯의 순서가 변경되면 Flutter는 새로운 위치에 있는 위젯의 상태를 유지하도록 관리합니다.

 

Key 를 활용한 UI 버그를 방지하는 방법 확인
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: MyHomePage()));
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final listTile = <Tile>[
    Tile(key: ValueKey('파란색'), color: Colors.blue, name: '파란색 타일'),
    Tile(key: ValueKey('빨간색'), color: Colors.red, name: '빨간색 타일'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('키가 없는 위젯을 만들어 보기'),
      ),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: listTile,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: swapTiles,
        child: Icon(Icons.swap_horiz),
      ),
    );
  } // end of build()

  // 첫번째 타일과 두번째 타일을 교환하는 기능
  void swapTiles(){
    // ['파란색타일', '빨간색타일']
    setState(() {
      // // 첫 번째 타일을 제거하고 그 타일을 반환하는 기능
      // // ['빨간색타일']
      // var removedTile = listTile.removeAt(0);
      // // 제거된 타일을 두 번째 위치로 삽입 하자.
      // listTile.insert(1, removedTile);

      // 축약해서 코드 작성
      listTile.insert(1, listTile.removeAt(0));

    });
  }

} // end of state class

class Tile extends StatefulWidget {
  final Color color; // 타일에 색상
  final String name; // 타일에 이름

  // Key 속성을 추가해서 부모 클래스(Sate) 고유 식별자를 보장한다.
  const Tile({required Key key,
    required this.color, required this.name}) : super(key: key);

  @override
  State<Tile> createState() => _TileState();
}

// 커스텀 Tile 클래스의 상태 관리 클래스 입니다.
class _TileState extends State<Tile> {
  // State 멤버 변수 widget 이런 멤버 변수를 제공해서 상위 클래스에 접근 할 수 ㅇㅆ도록 만들어 주고 있다.
  Color? currentColor; //현재 타일에 색상을 지정

  @override
  void initState() {
    super.initState();
    // 부모 클래스 변수에 접근해서 값을 가져 옴
    currentColor = widget.color;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: currentColor,
      width: 100,
      height: 100,
      alignment: Alignment.center,
      child: Text(
        widget.name,
        style: const TextStyle(
          color: Colors.white,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

 

💡핵심 정리

  1. Key의 기본 이해:
    • Key는 위젯 트리에서 각 위젯의 고유성을 보장하여 Flutter가 상태를 일관되게 관리하도록 도와줍니다. Key는 특히 위젯의 순서가 바뀌거나 새롭게 추가될 때 중요한 역할을 합니다.
  2. Key를 사용하지 않을 때 발생하는 문제:
    • Flutter는 동일한 타입의 위젯을 재사용하기 때문에, 순서 변경이나 상태 관리에 버그가 발생할 수 있습니다. Key가 없을 경우 Flutter는 어떤 위젯이 기존의 것인지 새로 생성된 것인지 구별하지 못할 수 있습니다.
  3. UI 버그 해결:
    • 리스트나 Row, Column과 같은 여러 위젯이 반복되는 레이아웃에서 Key를 사용하면 Flutter는 각 위젯을 고유하게 인식할 수 있으며, 이를 통해 UI가 의도치 않게 변경되는 것을 방지할 수 있습니다.
  4. Key의 종류와 사용 방법:
    • ValueKey와 같은 고유한 값 기반의 Key, UniqueKey와 같이 무작위로 생성되는 Key등이 있습니다
    • 각각의 Key는 특정 시나리오에서 유용하게 사용되며, 상태를 안전하게 유지하면서 UI 버그를 방지하는 데 도움이 됩니다.