본문 바로가기
flutter

플러터 - GetX로 상태 관리하기

by 들풀민들레 2023. 3. 13.

 

본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

GetX 준비하기


먼저 GetX를 사용하려면 pubspec.yaml 파일의 dependencies 항목에 다음처럼 get 패키지를 등록해야 합니다.

dependencies:
	get: ^4.6.5

GetX를 이용하면서 앱의 루트 위젯을 MaterialApp이 아닌 GetX에서 제공하는 Getmaterial App을 이용할 수도 있습니다. 사실 상태 관리나 종속성 관리를 목적으로 GetX를 사용한다면 GetMaterialApp을 사용하지 않아도 됩니다. GetMaterialApp 위젯은 GetX로 라우팅이나 스낵바, 국제화 기능을 구현할 때 사용합니다.

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final controller = Get.put(CounterController());
        return GetMaterialApp(
            home: Scaffold(
                appBar: AppBar(
                	title: Text('GetX Test'),
                ),
                body: MyWidget(),
            )
        );
    }
}

GetX 컨트롤러 선언하기


GetX의 상태 관리는 단순 상태 관리(GetBuilder)와 반응형 상태 관리(GetX, Obx)로 구분됩니다. 단순 상태 관리는 상탯값이 변경될 때 함수 호출로 변경 사항을 직접 적용해 줘야 하지만, 반응형 상태 관리는 자동으로 적용해 줍니다.
먼저 GetX의 단순 상태 관리 기법을 살펴보겠습니다. GetxController 클래스를 상속받는 개발자 클래스를 작성합니다. 이 클래스에 앱에서 이용할 상태가 변수를 선언하고, 상탯값을 내보내거나 변경하는 함수를 선언합니다. GetxController를 상속받아 작성한다는 것 말고 특별한 규칙은 없습니다. 즉, 꼭 재정의해야 하는 함수는 없습니다.
다음 코드는 int값을 상태로 유지하는 GetxController 클래스입니다. 어디선가 increment(), decrement() 함수가 호출되면 적절한 로직이 실행되어 상탯값을 변경합니다. 그리고 이 상탯값을 이용하는 위젯에 변경 사항을 적용하려면 update() 함수를 호출합니다.

class CounterController extends GetxController {
    int count = 0;
    void increment() {
        count++;
        update();
    }
    void decrement() {
        count--;
        update();
    }
}

GetxController에는 onInit()나 onClose() 같은 생명주기 함수를 선언할 수 있습니다. onInit() 함수는 GetxController를 생성할 때 자동으로 호출되며 onClose() 함수는 GetxController가 메모리에서 소멸할 때 자동으로 호출됩니다.

class CounterController extends GetxController {
    @override
    onInit() {
    	super.onInit();
    }
    @override
    onClose() {
    	super.onClose();
    }
}

GetX 컨트롤러 이용하기


GetxController를 위젯에서 이용하려면 GetX에 등록해야 하는데 2가지 방법이 있습니다. 먼저 Get.put() 함수의 매개변수로 GetxController를 등록하는 방법입니다. 다음 코드처럼 GetxController를 생성해 Get.put() 함수의 매개변수로 지정하면 등록되며 위젯에서 사용할 수 있습니다.

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        Get.put(CounterController());
        return GetMaterialApp(
            home: Scaffold(
                appBar: AppBar(
                	title: Text('GetX Test'),
                ),
                body: MyWidget(),
            )
        );
    }
}

Get.put() 함수를 이용하지 않고 GetBuilder의 init 속성에 GetxController를 등록할 수도 있습니다. GetBuilder는 GetX를 이용하는 위젯이며 GetBuilder를 선언한 곳부터 그 하위 위젯에서 이용할 GetxController를 init 속성에 등록할 수 있습니다.

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                appBar: AppBar(
                	title: Text('GetX Test'),
                ),
                body: GetBuilder(
                    init: CounterController(),
                    builder: (_) {
                    	return MyWidget();
                    },
                ),
            )
        );
    }
}

하위 위젯에서는 Get.find() 함수로 GetX에 등록된 GetxController 객체를 얻어서 사용합니다. 다음 코드에서는 build 함수의 첫 줄에 Get.find() 함수를 호출하여 CounterController 객체를 얻습니다. 이 객체로 GetxController에 등록된 상태를 이용하거나 함수를 호출하면 됩니다.

class MyWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final CounterController controller = Get.find();
        return Row(
            children: <Widget>[
                Text('GetX : ${controller.count}',),
                ElevatedButton(
                    child: Text('increment'),
                    onPressed: () {
                    	controller.increment();
                    },
                ),
                ElevatedButton(
                    child: Text('decrement'),
                    onPressed: () {
                    	controller.decrement();
                    },
                )
            ],
        );
    }
}

그런데 Get.find() 함수를 이용하지 않고 GetBuilder 위젯을 이용하면 GetBuilder의 builder에 등록한 함수가 자동으로 호출되면서 함수의 매개변수로 GetxController 객체가 전달됩니다.

class MyWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return GetBuilder<CounterController>(
            builder: (controller) {
                return Row(
                    children: <Widget>[
                        Text('GetX : ${controller.count}',),
                        ElevatedButton(
                            child: Text('increment'),
                            onPressed: () {
                                controller.increment();
                            },
                        ),
                        ElevatedButton(
                            child: Text('decrement'),
                            onPressed: () {
                            	controller.decrement();
                            },
                        )
                    ],
                );
            },
        );
    }
}

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

 

'flutter' 카테고리의 다른 글

플러터 - image_picker  (0) 2023.03.13
플러터 - BasicMessageChannel  (0) 2023.03.13
플러터 - Bloc Cubit  (0) 2023.03.13
플러터 - Provider  (0) 2023.03.13
플러터 - InheritedWidget  (0) 2023.03.13