추가된 라이브러리 :


http_util.dart 파일 추가
import 'package:dio/dio.dart';
final Dio dio = Dio(
BaseOptions(
baseUrl: "https://jsonplaceholder.typicode.com",
headers: {
"Content-Type": "application/json"
}
)
);
주요 구성 요소
- Dio 라이브러리 가져오기:
import 'package:dio/dio.dart';
Dio
라이브러리를 가져와서 HTTP 요청을 처리할 수 있도록 합니다.- Dio 인스턴스 생성:
Dio
:Dio
클래스의 인스턴스를 생성합니다.BaseOptions
:BaseOptions
클래스를 사용하여 기본 설정을 지정합니다.baseUrl
: 기본 URL을 설정합니다. 이 예제에서는 "https://jsonplaceholder.typicode.com"을 사용하여 API 요청의 기본 URL을 지정합니다.headers
: 요청 헤더를 설정합니다. 여기에는 "Content-Type"이 "application/json"으로 설정되어 있습니다. 이는 요청이 JSON 형식임을 나타냅니다.
final Dio dio = Dio(
BaseOptions(
baseUrl: "https://jsonplaceholder.typicode.com",
headers: {
"Content-Type": "application/json"
}
)
);
View
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockapp/post_page_vm.dart';
class PostBody extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
Post? model = ref.watch(postProvider);
if (model == null) {
return Center(child: CircularProgressIndicator());
} else {
return Column(
children: [
Text("id : ${model.id}"),
Text("userId : ${model.userId}"),
Text("title : ${model.title}"),
Text("body : ${model.body}"),
Row(),
],
);
}
}
}
동작 설명
- ConsumerWidget:
PostBody
클래스는ConsumerWidget
을 상속합니다. 이는build
메서드에서WidgetRef
객체를 사용하여 Riverpod 상태 공급자(provider)와 상호작용할 수 있게 합니다.
- Post 상태 구독:
ref.watch(postProvider)
메서드를 사용하여postProvider
의 현재 상태를 구독합니다. 이 상태는Post?
타입의model
변수에 저장됩니다.
- 상태 검사:
- 만약
model
이null
이라면, 데이터가 아직 로드되지 않은 상태로 간주하고CircularProgressIndicator
를 렌더링하여 로딩 중임을 표시합니다. - 만약
model
이null
이 아니라면, 데이터를 성공적으로 로드한 상태로 간주합니다.
- 데이터 표시:
Column
위젯을 사용하여Post
객체의 속성(id
,userId
,title
,body
)을 표시합니다.Row
위젯이 추가되어 있지만 내용이 없는 상태입니다. 콘텐츠를 추가하거나 제거할 수 있습니다.
ViewModel
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockapp/post_repository.dart';
class Post {
int userId;
int id;
String title;
String body;
Post(this.userId, this.id, this.title, this.body);
Post.fromMap(Map<String, dynamic> map) :
userId = map["userId"],
id = map["id"],
title = map["title"],
body = map["body"];
}
final postProvider = NotifierProvider<PostPageVM, Post?>(() {
return PostPageVM();
});
class PostPageVM extends Notifier<Post?> {
PostRepository repo = const PostRepository();
@override
Post? build() {
// 상태 초기화 시작
init();
// 상태 null 초기화
return null;
}
Future<void> init() async {
Post post = await repo.getPost();
state = post;
}
}
코드 설명
1. Post 클래스 (Model)
class Post {
int userId;
int id;
String title;
String body;
Post(this.userId, this.id, this.title, this.body);
Post.fromMap(Map<String, dynamic> map) :
userId = map["userId"],
id = map["id"],
title = map["title"],
body = map["body"];
}
Post 클래스
: 게시물 데이터를 나타냅니다.
fromMap(Map<String, dynamic> map)
: Map 객체를 받아서Post
객체를 초기화합니다.
2. NotifierProvider (State Management)
final postProvider = NotifierProvider<PostPageVM, Post?>(() {
return PostPageVM();
});
postProvider
:NotifierProvider
를 사용하여PostPageVM
의 인스턴스를 제공합니다.
3. PostPageVM 클래스 (ViewModel)
class PostPageVM extends Notifier<Post?> {
PostRepository repo = const PostRepository();
@override
Post? build() {
// 상태 초기화 시작
init();
// 상태 null 초기화
return null;
}
Future<void> init() async {
Post post = await repo.getPost();
state = post;
}
}
- PostPageVM:
Notifier
를 상속받아 상태 관리 및 데이터 로드를 처리합니다.
- repo:
PostRepository
인스턴스로, 데이터를 가져오는 역할을 합니다.
- build() 메서드: 초기 상태를 설정하고
init
메서드를 호출합니다.
- init() 메서드: 비동기적으로 데이터를 가져오고, 가져온 데이터를 상태(
state
)에 저장합니다.
Repository
// SRP : 데이터를 가져오는 곳 (휴대폰 디바이스(파일), 휴대폰 DB, Firebase(외부서버), 내서버, 공공데이터서버)
import 'package:dio/dio.dart';
import 'package:mockapp/http_util.dart';
import 'post_page_vm.dart';
class PostRepository {
const PostRepository();
Future<Post> getPost() async{
Response response = await dio.get("/posts/1"); // json 타입은 dio의 경우 Map 타입으로 받아준다.
Map<String, dynamic> body = response.data;
return Post.fromMap(body);
}
}
- Dio 라이브러리 가져오기:
Dio
를 사용하여 API 요청을 보냅니다.
import 'package:dio/dio.dart';
import 'package:mockapp/http_util.dart';
import 'post_page_vm.dart';
- PostRepository 클래스 정의:
class PostRepository {
const PostRepository();
}
PostRepository
클래스를 정의하고, 데이터를 가져오는 기본 역할을 담당합니다. 생성자는 상수 생성자이므로 불변 객체로 만들 수 있습니다.- getPost() 메서드:
Future<Post> getPost() async {
Response response = await dio.get("/posts/1");
Map<String, dynamic> body = response.data;
return Post.fromMap(body);
}
"/posts/1"
endpoint에서 데이터를 가져옵니다.Dio
의 응답 데이터를 Map<String, dynamic>
타입으로 변환합니다.Map
객체를 사용하여 Post
객체를 생성하고 반환합니다.아래의 라이브러리는 log를 보기 좋게 사용하기 위한 라이브러리 입니다. (필수 다운 필요 X)


Share article