비동기 작업(SharedPreference)과 setState()

샤워실의 바보·2024년 2월 28일
0
post-thumbnail
post-custom-banner
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:toonflix/models/webtoon_detail_model.dart';
import 'package:toonflix/models/webtoon_episode_model.dart';
import 'package:toonflix/services/api_service.dart';
import 'package:toonflix/widgets/episode_widget.dart';

class DetailScreen extends StatefulWidget {
  final String title, thumb, id;

  const DetailScreen({
    super.key,
    required this.title,
    required this.thumb,
    required this.id,
  });

  
  State<DetailScreen> createState() => _DetailScreenState();
}

class _DetailScreenState extends State<DetailScreen> {
  late Future<WebtoonDetailModel> webtoon;
  late Future<List<WebtoonEpisodeModel>> episodes;
  late SharedPreferences prefs;
  bool isLiked = false;

  Future initPrefs() async {
    prefs = await SharedPreferences.getInstance();
    final likedToons = prefs.getStringList('likedToons');
    if (likedToons != null) {
      if (likedToons.contains(widget.id) == true) {
        setState(() {
          isLiked = true;
        });
      }
    } else {
      await prefs.setStringList('likedToons', []);
    }
  }

  
  void initState() {
    super.initState();
    webtoon = ApiService.getToonById(widget.id);
    episodes = ApiService.getLatestEpisodesById(widget.id);
    initPrefs();
  }

  onHeartTap() async {
    final likedToons = prefs.getStringList('likedToons');
    if (likedToons != null) {
      if (isLiked) {
        likedToons.remove(widget.id);
      } else {
        likedToons.add(widget.id);
      }
      await prefs.setStringList('likedToons', likedToons);
      setState(() {
        isLiked = !isLiked;
      });
    }
  }

initPrefs 메서드 내에서 setState를 사용하는 이유는, 애플리케이션의 상태가 비동기적으로 초기화되고, 해당 상태 변경이 UI에 반영되어야 할 때 필요합니다. SharedPreferences에서 좋아하는 웹툰 목록을 비동기적으로 로드한 후, 현재 웹툰이 사용자가 좋아하는 목록에 포함되어 있는지 확인합니다. 만약 포함되어 있다면, isLiked 상태를 true로 설정해 UI에 '좋아요' 상태를 반영해야 합니다.

Flutter에서 UI를 업데이트 하기 위해서는 setState 메서드를 호출하여 위젯 트리를 다시 빌드해야 합니다. initPrefs 메서드가 비동기적으로 실행되기 때문에, SharedPreferences로부터 데이터를 성공적으로 불러온 후 상태를 업데이트 하려면 setState 내에서 상태를 변경해야 합니다. 이를 통해 isLiked 상태가 변경될 때 Flutter가 해당 변경 사항을 감지하고, 관련된 위젯들을 적절히 다시 빌드할 수 있도록 합니다.

그러나, initState에서 비동기 작업을 직접 실행하는 것은 권장되지 않습니다. 대신, initState 내에서 비동기 작업을 시작만 하고, 비동기 작업이 완료되면 그 때 상태를 업데이트하는 방식으로 처리해야 합니다. initPrefs 같은 경우는 initState 내에서 호출되지만, 실제 상태 변경 (setState 호출)은 비동기 작업이 완료된 이후에 발생합니다. 따라서 이 경우는 안전하게 setState를 사용하는 예시입니다.

profile
공부하는 개발자
post-custom-banner

0개의 댓글