Flutter Hooks: https://github.com/rrousselGit/flutter_hooks
Flutter Hooks는 React의 Hooks와 이를 분석한 미디엄 글을 보고 영감을 받아 flutter에 맞도록 hook 을 구현한 패키지이다. Stateful
과 Stateless
를 구분할 필요 없이 하나의 HookWidget
으로 모든 위젯을 표현할 수 있도록 도와주며, 위젯 lifecycle 및 로컬 state 관리와 관련하여 다양한 편의성을 제공한다.
본 글에서는 간단하게 flutter_hooks
패키지를 사용하는 법을 살펴보도록 한다.
패키지 설치는 여타 다른 패키지나 플러그인 설치와 동일하다. 실제 앱의 위젯을 구성하는데 사용될 위젯 패키지 이므로 pubspec.yaml
의 dependencies
섹션에 추가하면 된다.
# pubspec.yaml 파일
dependencies:
flutter_hooks: any
이후 다른 패키지 설치와 동일하게 flutter pub get
을 수행하면 된다.
간단한 샘플 앱 2개를 보면서 사용법을 알아보자. 아래는 AnimationController
의 사용이 필요한 StatefulWidget
을 다루는 예제이다.
class AnimationWidget extends StatefulWidget {
const AnimationWidget({Key key, @required this.duration}) : super(key:key);
final Duration duration;
@overrider
_AnimationWidgetState createState() => _AnimationWidgetState();
}
class _AnimationWidgetState extends State<Example> with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
// 로직과 상관없는 코드 #1 - 컨트롤러 초기화
_controller = AnimationController(vsync: this, duration: widget.duration);
}
@override
void didUpateWidget(Example oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.duration != oldWidget.duration) {
_controller.duration = widget.duration; // 로직과 상관없는 코드 #2 - 업데이트
}
}
@override
void dispose() {
_controller.dispose(); // 로직과 상관없는 코드 #3 - 컨트롤러 해제
}
@override
Widget build(BuildContext context) {
return Container();
}
}
StatefulWidget
과 그에 따른 state를 정의하기 위한 State
클래스, 그리고 애니메이션 사용을 위한 mixin 추가를 위한 with
까지, 클래스 생성부터 부가적인 코드가 너무 많이 들어있는 것을 볼 수 있다. 또한 AnimationController
의 안전한 할당/해제를 위한 lifecycle 메소드까지 들어가서, 실제 UI나 로직을 위한 코드가 들어가는 build
메소드 외에 수십줄이 추가됨을 알 수 있다.
flutter_hooks
는 이러한 부가적인 코드를 대신하여 실제 플러터 개발자는 온전히 UI와 로직에만 신경쓸 수 있도록 도와주는 위젯 패키지 이다. 기본적으로 Stateful이나 Stateless 위젯 대신 HookWidget
을 상속하여 원하는 위젯을 개발하면 되고, 기타 state 관리나 생명주기 관리 등은 같이 제공 되는 기본 Hooks
를 사용하거나, Hooks
를 커스텀하여 사용할 수 있다.
위의 코드를 flutter_hooks 를 이용해 간소화 시킨 코드는 아래와 같다.
import 'package:flutter_hooks/flutter_hooks.dart';
class AnimationWidget extends HookWidget {
const AnimationWidget({Key key, @required this.duration}):super(key:key);
@override
Widget build(BuildContext context) {
final controller = useAnimationController(duration:duration);
return Container(
/* controller를 사용하는 코드 추가 */
);
}
}
거의 1/3 수준으로 줄어든 코드량을 볼 수 있다. 이는 flutter_hooks가 미리 정의한 useAnimationController
가 필요한 작업을 모두 대신해주기 때문이다. 본 글은 소개를 위한 글이므로 구현에 대한 자세한 설명은 생략한다.
플러터 기본 예제인 카운터를 비롯하여 다양한 위젯에서 데이터 변경에 따라 위젯을 업데이트 하고 싶은 경우 StatefulWidget
과 setState
를 사용한다. 그러나 이러한 코드는 위의 애니메이션 예제에서 보여줬듯이 부수적인 코딩을 요구한다. flutter_hooks를 사용하면 이 또한 간단하게 줄일 수 있다.