1. 정의 및 사용 의도

사용자들은 앱을 사용하면서 특정한 게시물을 추천하기도 하고, 댓글을 남기기도 합니다. 이러한 상태 변화를 바로 적용시키기 위해서 Flutter에서는 setState() 메소드를 사용합니다. setState() 메소드는 상태를 업데이트하고 현재 위젯 및 하위 위젯들을 다시 빌드하고 UI를 다시 그리는 작업을 수행하기 때문에, 위젯이 많아져 위젯 트리가 커진다면 상태가 변하지 않아 굳이 빌드를 다시 할 필요가 없는 위젯들까지 다시 빌드하고, 이 과정에서 성능 저하를 초래할 수 있으며, 같은 상태를 유지해야 하는 위젯 A와 B가 있을 때 A의 변경된 상태를 B가 알지 못 해 A에서 발생한 이벤트로 B의 상태를 업데이트하지 못 한다는 단점이 있습니다.

따라서, 큰 프로젝트를 수행하려면 상태 관리에 필요한 라이브러리를 사용하는 것이 불가피해집니다. 우리는 그 중에서 가장 많이 사용되는 상태 관리 패키지인 Provider를 사용하기로 하였습니다. Provider는 굳이 상태가 변하지 않아 다시 빌드할 필요가 없는 위젯들까지 불필요하게 다시 빌드 및 UI 렌더링을 하지 않으며, 위젯에게 의존성을 주입하여 사용하는 방식을 취하고 있습니다.

2. 구현 방법

우선 pubspec.yaml 파일의 dependencies에 다음과 같은 코드를 추가합니다.

dependencies:
	provider: ^<최신 버전>

그리고 pub get을 클릭하면 provider 패키지를 설치하게 되고, 이제 provider를 import하여 사용할 수 있습니다.

import 'package:provider/provider.dart';

먼저, Provider를 사용하려면 ChangeNotifier 클래스를 상속받는 클래스를 선언해야 합니다. 여기서는 Json 파싱 후 데이터 관리를 위하여 Recipe 타입의 List를 선언하여, 데이터를 fetch해주는 메소드를 호출해서 데이터를 가져온 후 notifyListeners() 메소드를 사용하여 상태 변화를 파악해 알리고 위젯을 다시 빌드할 수 있게 해 줍니다.

class RecipeProviders extends ChangeNotifier {
  RecipeRepository _recipeRepository = RecipeRepository();

  List<Recipe> _recipes = [];
  List<Recipe> get recipes => _recipes;

  loadRecipes() async {
    List<Recipe>? listRecipes = await _recipeRepository.fetchRecipe(http.Client());
    _recipes = listRecipes!;
    notifyListeners();
  }
}

이 ChangeNotifier를 상속받은 RecipeProviders 클래스를 앱에 전달해주기 위하여 ChangeNotifierProvider 위젯을 사용할 것입니다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (BuildContext context) => RecipeProviders(),
        ),
        ChangeNotifierProvider(
          create: (BuildContext context) => LexProviders(),
        ),
      ],
      child: MaterialApp(
        theme: ThemeData(
          primaryColor: Color(0xffBE5215), // 테마 색상은 Figma에서 정한 #BE5215로 설정
        ),
        home: MainPage(),
      ),
    );
  }
}