Flutter Provider 상태관리의 즐거움 ~!

houndhollis·2023년 12월 18일
0
post-thumbnail

이렇게 월요일은 필수적으로 벨로그를 작성하고 있다, 그러면 그만큼 시간이 빨리가서 또 다음주 월요일..? 크리스마스인데 쓸려나... 쓸꺼같긴 하다 오늘은 휴가였어서 집에서 공부를 조금 했다. 흐흐 .. 역시 휴가는 좋은 것!

Provider 상태관리,

뭔가 순서가 이상하다.. 리버팟 보다 먼저 했어야 했다고 생각했는데 바뀌었다.

flutter pub add provider

터미널에 입력해서 패키지를 준비해준다. 공부 했던 자료에서는

모든 데이터를 담당해줄 service를 별도 파일로 만들어서 관리를 했다.

class BookService extends ChangeNotifier {
  List<Book> bookList = []; // 책 목록
}

이런식으로 작성을 해줬다. Book 같은 경우 model 로 분리해뒀다,

Provider 를 이용하여 BookService 를 위젯 트리의 꼭대기에 배치하고, 어디서든 쉽게 접근할 수 있도록 만들어 준다. ChangeNotifier는 상태를 관리하기 위한 클래스이다. 상태가 변경되면 notifyListeners() 함수를 호출하여 상태를 구독하는 위젯에 알릴수도 있다.

runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => BookService()),
      ],
      child: const MyApp(),
    ),
  );

사용기

자 이제는 어느정도 셋팅이 끝났다.. 한번 사용해볼떄다.
간편하게 빌더 위젯을 만들어 주고 Consumer 위젯으로 바꿔준다.

Consumer<BookService>(
	builder: (context, bookService, child) { 
		return 위젯;
	}
)

BookService 타입을 넣어주고 builder 에는 2가지 파라미터가 추가로 들어간다.
-> bookService, child

bookService 변수를 통해 BookService 안에 있는 변수에 접근해 수정하고, 화면을 새로고침할 수 있습니다.

child 매개변수는 Consumer 위젯의 자식 위젯입니다. Consumer 위젯은 상태가 변경될 때마다 자식 위젯을 다시 그립니다. 따라서 bookService 매개변수를 사용하여 BookService 에서 값이 변경되는 경우, StatefulWidget의 setState와 같이 notifyListeners();를 호출하는데, 이 때 해당 서비스의 Consumer로 등록된 모든 위젯의 builder 함수가 재호출 되면서 화면이 갱신 됩니다.

위에 내용이 상태관리를 통해 값을 변경 하여, 다시 그릴수 있는 거다.

return Consumer<BookService>(
      builder: (context, bookService, child) {
        List<Book> bookList = bookService.bookList;

        return Scaffold(

아래 처럼 bookList 라는 변수로 bookService.bookList 로 접근이 가능하다.

위에 방법 처럼, 불러올수 있지만.

context.read<클래스명>(); 를 이용하면 위젯 트리 상단에 있는 
Provider로 등록한 클래스에 접근할 수 있습니다.

중요한 Tip
변화에 따라 화면을 새로 그려줄 필요가 있을 때는 Consumer 를 사용하며, 화면을 새로고침할 필요없이 BookService 의 변수나 함수만 이용하고자 한다면 context.read<클래스명>() 를 사용해도 됩니다.

예시1

만약 우리가 bookList 에서 즐겨찾기 button을 누를 경우 likedBookList 로 보내고 싶을때 간단하게 함수를 작성할수 있다.

List<Book> bookList = []; // 책 목록
List<Book> likedBookList = []; // 좋아요 누른 책 목록

  void toggleLikeBook({required Book book}) {
    String bookId = book.id;
    if (likedBookList.map((book) => book.id).contains(bookId)) {
      likedBookList.removeWhere((book) => book.id == bookId);
    } else {
      likedBookList.add(book);
    }
    notifyListeners();
  }

toggleLikeBook 함수를 통해 분기처리를 해주고 마지막에 notifyListeners();
작성 해줘서 BookService를 구독하는 위젯이 리렌더링을 시켜줘서 setState 및 하위 자식 위젯에서도 상태를 즉각 반영 시킬수 있도록 작업도 할수 있다.

provider를 사용하고 riverpod도 사용했지만. 둘다 정말 쉽고 간편한거 같다.

추후에는 이렇게만 관리할게 아니라. shared_preferences 패키지를 사용하여, 한번 내부 데이터 저장 공간에 데이터를 저장하고 재실행 했을 경우에도 데이터를 유지할수 있게끔 작업을 추가로 해보겠다! 그럼 오늘은 여기까지~

profile
한 줄 소개

0개의 댓글