해결된 질문
작성
·
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
안녕하세요.
Provider로 되어 있는 CartService
를 Riverpod으로 변경한 결과 공유드립니다.
기존에도 불변 객체를 활용하도록 구현되어 있어서 기존 로직을 그대로 활용하되 notifyListeners();
를 제거하였습니다.
List<CartItem> _cartItemList = const [];
가 Riverpod Notifier
의 state
로 변경되었으니 기존 _cartItemList
를 state
로 변경해주시면 됩니다.
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();
}
}
감사합니다 :)
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();
}
넘 감사합니다.