• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    해결됨

CatService 를 수정해보고 싶은데 잘 안되어 도움 요청드립니다.

23.12.29 00:53 작성 조회수 112

1

안녕하세요.

CatService 를 Riverpod 로 변경해보고 싶은데 잘 안되어 도움 요청드립니다.

class CatService extends ChangeNotifier {
  // 고양이 사진을 담을 변수
  List<String> catImages = [];

  // 좋아요 사진
  List<String> favoriteImages = [];

  Dio dio = Dio();

  SharedPreferences prefs;

  // 생성자
  CatService(this.prefs) {
    dio.interceptors.add(LogInterceptor());
    dio.interceptors.add(CustLogInterceptor());
    getRandomCatImages();
    favoriteImages = prefs.getStringList(FavoriteImage_KEY) ?? [];
  }

  void getRandomCatImages() async {
    Response resp = await dio.get(
        'https://api.thecatapi.com/v1/images/search?limit=10&mime_types=jpg');
    print(resp.data);
    for (int i = 0; i < resp.data.length; i++) {
      final map = resp.data[i];
      catImages.add(map['url']); // url만 추출하여 catImages 에 이미지 추가.
    }
    notifyListeners();
  }

  // 좋아요 토글
  void toggleFavoriteImage(String catImage) {
    if (favoriteImages.contains(catImage)) {
      favoriteImages.remove(catImage); // 이미 좋아요한 경우 제거
    } else {
      favoriteImages.add(catImage); // 새로운 사진 추가
    }
    notifyListeners(); // 새로고침
  }
}

위 코드를 아래와 같이 Riverpod 로 변경해보고 싶습니다.

final dioProvider = Provider<Dio>((ref) {
  final dio = Dio();

  dio.interceptors.add(LogInterceptor());
  return dio;
});
final catImageProvider = NotifierProvider<CatImageNotifier, List<String>>(CatImageNotifier.new);
final favoriteImageProvider = NotifierProvider<FavoriteImageNotifier, List<String>>(FavoriteImageNotifier.new);

class CatImageNotifier extends Notifier<List<String>> {
  // 고양이 사진을 담을 변수
  List<String> catImages = [];

  @override
  List<String> build() => [];

  void getRandomCatImages() async {
    final resp = await ref.read(dioProvider).get(
        'https://api.thecatapi.com/v1/images/search?limit=10&mime_types=jpg');
    for (int i = 0; i < resp.data.length; i++) {
      final map = resp.data[i];
      catImages.add(map['url']); // url만 추출하여 catImages 에 이미지 추가.
    }
    state = catImages;
  }

}

class FavoriteImageNotifier extends Notifier<List<String>> {
  // 좋아요 사진
  //List<String> favoriteImages = [];

  @override
  List<String> build() => [];

  // 좋아요 토글
  void toggleFavoriteImage(String catImage) {
    if (state.contains(catImage)) {
      state.remove(catImage); // 이미 좋아요한 경우 제거
    } else {
      state.add(catImage); // 새로운 사진 추가
    }

  }

}

배열이 2개라서 두개의 Notifier 를 상속받은 클래스로 나눠야 할 것 같은 생각이 들어 나눠보려고 하는데 잘 안됩니다.

어떻게 수정해야 되는지 도움 부탁드립니다.

Class 를 하나 만들어서 id, imgUrl, isFavorite 3개의 칼럼으로 구분을 지어서 하면 해결될지 고민되기도 합니다.

답변 1

답변을 작성해보세요.

1

안녕하세요

 

CatImageNotifier의 상태가 List<String>이므로 catImage 속성을 남겨둘 필요는 없어보입니다.

FavoriteImageNotifier의 경우 state의 reference가 변경되어야 변경사항 알림이 전파되므로 add()remove()를 이용하시면 안됩니다.

아래 코드를 참고해 주세요.

final catImageProvider = NotifierProvider<CatImageNotifier, List<String>>(CatImageNotifier.new);
final favoriteImageProvider = NotifierProvider<FavoriteImageNotifier, List<String>>(FavoriteImageNotifier.new);

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

  void getRandomCatImages() async {
    final resp = await ref.read(dioProvider).get(
        'https://api.thecatapi.com/v1/images/search?limit=10&mime_types=jpg');
    List<String> catImages = [];
    for (int i = 0; i < resp.data.length; i++) {
      final map = resp.data[i];
      catImages.add(map['url']);
    }
    state = catImages;
  }

}

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

  // 좋아요 토글
  void toggleFavoriteImage(String catImage) {
    if (state.contains(catImage)) {
      // state의 reference가 변경되어야 변경사항 알림이 전파되므로 remove를 쓰면 안됩니다.
      // state.remove(catImage);
      state = state.where((e) => e != catImage).toList();
    } else {
      // state의 reference가 변경되어야 변경사항 알림이 전파되므로 add를 쓰면 안됩니다.
      // state.add(catImage);
      state = [...state, catImage];
    }
  }

}

감사합니다 :)

Link님의 프로필

Link

질문자

2023.12.29

너무 감사합니다.

덕분에 Provider 상태관리 예제와 Riverpod 예제에 대한 이해도가 많이 높아졌습니다.