[Flutter] getX 활용법 - 반응형 상태 관리

mi-fasol·2023년 3월 26일
0

Flutter

목록 보기
7/7

저번에는 간단한 예시와 함께 단순 상태 관리에 대해 알아보았다.

지난 게시물에서 얘기한대로, 오늘은 반응형 상태 관리에 대해 알아보겠다.

반응형 상태 관리와 단순 상태 관리의 차이점은 지난 게시글에서 다뤘으니, 오늘은 예시 코드와 코드 해석만 간단히 짚고 넘어갈 예정이다.

반응형 상태 관리는 변수를 선언하는 방법이 조금 독특하다.
reactive_controller.dart의 코드를 보며 확인해보자.

import "package:get/get.dart";

class ReactiveController extends GetxController {
  RxInt count = 0.obs;
  void increase() {
    count++;
  }
}

반응형 상태 관리를 사용하려면, 변수 타입 앞에 Rx를 추가하고 변수 뒤에 .obs를 붙이면 된다.

  • obs: 따로 타입을 지정하지 않고, 컨트롤러에서 선언한 변수의 변화를 감지했을 때 바로 update 가능
  • RxInt 변수명 = 0.obs; // 정수형
  • RxDouble 변수명 = 0.0.obs; // 실수형
  • RxString 변수명 = "".obs; // 문자열
  • Rx<클래스명> 변수명 = 클래스(인자).obs;
    = RxList<배열 타입> 변수명 = [].obs;

increase 함수는 별반 다를 게 없다.
이전 게시물에서 말했듯이 반응형 상태 관리는 provider의 notifyListener()나, 단순 상태 관리의 update() 등 상태 변경을 알리는 함수를 사용하지 않아도 된다는 차이점 정도가 있겠다.

그 다음은 reactive_getx.dart의 코드다.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx/controller/reactive_controller.dart';

class ReactiveGetX extends StatelessWidget {
  const ReactiveGetX({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    final controller = Get.put(ReactiveController());

    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        GetBuilder<ReactiveController>(builder: (controller) {
          return Obx(() => Text(
                "${controller.count}",
                style: const TextStyle(
                  fontSize: 50,
                ),
              ));
        }),
        ElevatedButton(
            onPressed: controller.increase,
            child: const Text(
              "+",
              style: TextStyle(
                fontSize: 30,
              ),
            ))
      ],
    ));
  }
}

이전 게시글의 with_getx.dart 파일과 동일한 폼이지만, 다른 코드가 하나 있다.
바로 Obx() =>를 통해 텍스트를 선언해줬다는 것이다.

  • Obx(): 컨트롤러를 명시하지 않아도 위젯을 반환해주는 함수

이전 with_getx.dart 코드에서는

GetBuilder<IncreaseController>(builder: (controller) {
          return Text(
            "${controller.count}",
            style: const TextStyle(
              fontSize: 50,
            ),
          );
        }),

이랬던 코드가, 반응형 상태 관리를 적용하면

Obx(() => Text(
              "${controller.count}",
              style: const TextStyle(
                fontSize: 50,
              ),
            )),

이렇게 변한다.
Obx()를 사용하여 빌더를 통해 컨트롤러를 명시해줘야 했던 불편함을 덜어줄 수 있다.

또는

GetX(builder: (_) {
          return Text(
            "${Get.find<ReactiveController>().count.value}",
            style: const TextStyle(
              fontSize: 50,
            ),
          );
        })

이런 식으로 코드를 변경할 수도 있다. 보여지는 결과는 차이가 없고, 코드의 로직만 살짝 바뀐 것이다.
무엇을 쓸지는 본인 취향이지만, Obx()가 조금 더 깔끔해 보이기는 한다.

main.dart의 코드는 이전 코드의 WithGetx()를 ReactiveGetx()로 바꾸면 되므로 생략하고 넘어가도록 하겠다.

반응형 상태 변경의 또다른 장점으로는, 값이 변경이 되어야만 리렌더링이 된다는 것이다.
이를 통해 불필요한 랜더링을 확실하게 줄일 수 있다.

예를 들어, reactive_getx.dart에 아래와 같은 버튼을 하나 더 추가했다고 가정해보자.

ElevatedButton(
            onPressed: () {
              controller.makeIt();
            },
            child: const Text(
              "make it 0",
              style: TextStyle(
                fontSize: 30,
              ),
            ))

onPressed에 선언된 makeIt 함수를 사용하기 위해 reactive_controller.dart에 아래와 같은 함수를 추가해야 한다.

void makeIt() {
    count(0);
  }
  • count(0): count라는 변수에 0 삽입

그리고 생긴 make it 0 버튼을 눌러도 값은 이미 0이기 때문에 화면이 랜더링 되지 않는다.

혹시 정말 그런지 궁금하신 분이 계시다면, Text 위젯에 print("rendering");을 추가해서 버튼을 눌렀을 때 콘솔에 나타나는지 확인해보시면 된다.

이렇게 간단한 반응형 상태 관리의 코드를 확인해 보았는데, getX는 알면 알수록 참 편리한 것 같다.

다음에는 getX의 의존성 주입에 대해 알아보겠다.

profile
정위블

0개의 댓글