인프런 커뮤니티 질문&답변

Link님의 프로필 이미지
Link

작성한 질문수

Flutter 앱 개발 실전

ProductRepository 의존성 주입

riverpod 코드 변경 질문

해결된 질문

작성

·

190

1

안녕하세요.

Provider 로 된 코드를 Riverpod 로 변경 해보려고 하면 벽에 부딪쳐네요.

class CartService with ChangeNotifier {
  List<CartItem> _cartItemList = const [];
  List<CartItem> get cartItemList => _cartItemList; // 상품 목록

  // 선택된 상품 목록
  List<CartItem> get selectedCartItemList {
    return _cartItemList.where((cartItem) => cartItem.isSelected).toImmutable();
    // cartItemList에서 isSelected 값이 true 항목만 불변 배열로 반환하는 Getter를 구현
  }

  // 상품 추가
  void add(CartItem newCartItem){
    _cartItemList = [..._cartItemList, newCartItem].toImmutable();
    notifyListeners();
  }

  // 상품 수정
  void update(int selectedIndex, CartItem newCartItem) {
    _cartItemList = _cartItemList.asMap().entries.map((entry) {
      return entry.key == selectedIndex ? newCartItem : entry.value;
    }).toImmutable();
    notifyListeners();
    /***
     * 업데이트하고 싶은 항목의 인덱스인 selectedIndex에 해당하는 항목을
     * 새로운 newCartItem으로 변경하여 새로운 불변 배열을 생성하도록 구현
     */
  }

  // 상품 삭제
  void delete(List<CartItem> deleteList){
    _cartItemList = _cartItemList.where((cartItem) {
      return !deleteList.contains(cartItem);
    }).toImmutable();
    notifyListeners();
    /***
     * 삭제하고 싶은 목록을 deleteList로 전달받고,
     * 해당 배열에 들어있지 않은 CartItem만 남긴 불변 배열을 생성하도록 구현
     */
  }
}

 

위 코드를 아래와 같이 변경하고자 일부 구현을 해보고 있습니다.

틀린 부분 수정 및 상품 수정 코드를 어떻게 추가해야 될까요?

final cartProvider = NotifierProvider<CartNotifier, List<CartItem>>(CartNotifier.new);

class CartNotifier extends Notifier<List<CartItem>> {
  @override
  List<CartItem> build() => const []; // 상품 목록

  // 상품 추가
  void add(CartItem newCartItem){
    state = [...state, newCartItem];
    // state 는 immutable 데이터이기 때문에 직접적으로 state 를 변경할 수 없다.
  }

  // 상품 삭제
  void delete(List<CartItem> deleteList){
    state = state.where((cartItem) => cartItem != deleteList).toList();
  }

  // 상품 수정
  void update(int selectedIndex, CartItem newCartItem) {
    // CartItem 에 유니크한 id 값이 없는 거 같고, 선택한 index 값으로 찾아서 update 해야 하는데 모르겠음.

  }

  /*
  state = [
      for (final item in state)
        if (item.id == id)
          newCartItem
        else
          item,
    ];
   */

  // 선택된 상품 목록
  List<CartItem> get selectedCartItemList {
    return state.where((cartItem) => cartItem.isSelected).toList();
  }

}

 

 

답변 1

1

DevStory님의 프로필 이미지
DevStory
지식공유자

안녕하세요.

Provider로 되어 있는 CartService를 Riverpod으로 변경한 결과 공유드립니다.

  • 기존에도 불변 객체를 활용하도록 구현되어 있어서 기존 로직을 그대로 활용하되 notifyListeners();를 제거하였습니다.

  • List<CartItem> _cartItemList = const [];가 Riverpod Notifierstate로 변경되었으니 기존 _cartItemListstate로 변경해주시면 됩니다.

final cartProvider = NotifierProvider<CartNotifier, List<CartItem>>(CartNotifier.new);


class CartService extends Notifier<List<CartItem>> {
  @override
  List<CartItem> build() => const [];

  /// 선택된 상품 목록
  List<CartItem> get selectedCartItemList {
    return state.where((cartItem) => cartItem.isSelected).toImmutable();
  }

  /// 상품 추가
  void add(CartItem newCartItem) {
    state = [...state, newCartItem].toImmutable();
  }

  /// 상품 수정
  void update(int selectedIndex, CartItem newCartItem) {
    state = state.asMap().entries.map((entry) {
      return entry.key == selectedIndex ? newCartItem : entry.value;
    }).toImmutable();
  }

  /// 상품 목록 삭제
  void delete(List<CartItem> deleteList) {
    state = state.where((cartItem) {
      return !deleteList.contains(cartItem);
    }).toImmutable();
  }
}

감사합니다 :)

Link님의 프로필 이미지
Link
질문자

넘 감사합니다.

Link님의 프로필 이미지
Link
질문자

Android Studio 에서 위 코드로 테스트를 하니까 toImmutable() 에 에러 표시줄이 생기네요.

그래서 아래와 같이 코드 변경했습니다.

final cartProvider =
    NotifierProvider<CartNotifier, List<CartItem>>(CartNotifier.new);

class CartNotifier extends Notifier<List<CartItem>> {
  @override
  List<CartItem> build() => const []; // 상품 목록

  // 상품 추가
  void add(CartItem newCartItem) {
    state = [...state, newCartItem];
    // state 는 immutable 데이터이기 때문에 직접적으로 state 를 변경할 수 없다.
  }

  // 상품 삭제
  void delete(List<CartItem> deleteList) {
    state = state.where((cartItem) => !deleteList.contains(cartItem)).toList();
  }

  // 상품 수정
  void update(int selectedIndex, CartItem newCartItem) {
    state = state
        .asMap()
        .entries
        .map((entry) => entry.key == selectedIndex ? newCartItem : entry.value)
        .toList();
  }

  // 선택된 상품 목록
  List<CartItem> get selectedCartItemList =>
      state.where((cartItem) => cartItem.isSelected).toList();

}
DevStory님의 프로필 이미지
DevStory
지식공유자

toImmutable() 함수는 별도로 직접 만든 함수라서 에러가 발생하시는 것 같습니다. 자세한 내용은 강의를 참고해 주세요 :)

Link님의 프로필 이미지
Link

작성한 질문수

질문하기