[flutter] FutureBuilder - 비동기 Builder

곽준영·2023년 3월 31일
0
post-thumbnail

비동기 Builder를 사용하는 방법을 알아보자

먼저,
동기 - 요청과 결과가 동시에 일어난다.
비동기 - 요청과 결과가 동시에 일어나지 않는다.

class Info

class Info {
  final String email;
  final String nickname;
  final String as_mail;
  final String level;

  Info({
    required this.email,
    required this.nickname,
    required this.as_mail,
    required this.level,
  });

  factory Info.fromJson(Map<String, dynamic> json) {
    return Info(
      email: json["email"],
      nickname: json["nickname"],
      as_mail: json["as_mail"],
      level: json["level"],
    );
  }
}

FutureBuilder

late Future<List<Info>> info;

void initState() {
	info = fetchInfo();
}

Future<List<Info>> fetchInfo() async {
    var url =
        '${Provider.of<SystemProvider>(context, listen: false).mainDomain}/api/member/my_account.php?email=' +
            email;
    print(url);
    final response = await http.post(Uri.parse(url));

    if (response.statusCode == 200) {
      //만약 서버가 ok응답을 반환하면, json을 파싱합니다
      //print('응답했다');
      //print(json.decode(response.body));
      Map<String, dynamic> map = json.decode(response.body);
      List<dynamic> body = map["result"];

      List<Info> allInfo =
          body.map((dynamic item) => Info.fromJson(item)).toList();
      nicknameController.text = allInfo[0].nickname.toString();
      inputController.text = allInfo[0].as_mail.toString();
      return allInfo;
    } else {
      //만약 응답이 ok가 아니면 에러를 던집니다.
      throw Exception("네트워크 오류");
    }
  }


Container(
                              margin:
                                  const EdgeInsets.only(left: 21, bottom: 23),
                              child: SizedBox(
                                width: MediaQuery.of(context).size.width - 111,
                                child: FutureBuilder<List<Info>>(
                                  future: info,
                                  builder: (context, snapshot) {
                                    if (snapshot.hasData) {
                                      return buildList(snapshot.data);
                                    } else if (snapshot.hasError) {
                                      print(snapshot.error);
                                      return Text("${snapshot.error}에러!!");
                                    }
                                    return Container();
                                  },
                                ),
                                // as_mail == ""
                                //     ? TextField(
                                //         decoration: InputDecoration(
                                //             hintText: "abcd123@gmail.com"),
                                //       )
                                //     : Text(as_mail),
                              ),
                              // const Text(
                              //   'abcd123@gmail.com',
                              //   style: GoogleFonts.notoSans(fontWeight: FontWeight.w400),
                              // ),
                            ),

buildList

Widget buildList(snapshot) { 
    return Container(      
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [         
          TextField(
              style: GoogleFonts.notoSans(decorationThickness: 0),
              enabled: sub_email_enabled,
              focusNode: sub_focus_node,
              controller: inputController,
              decoration: InputDecoration(
                  enabledBorder: InputBorder.none,
                  disabledBorder: InputBorder.none,
                  focusColor: Colors.blue,
                  hoverColor: Colors.white)),
        ],
      ),
    );
  }

단순하게 정리

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '밑에 결과는 비동기 빌더로 가지고 오는 값',
              style: TextStyle(fontSize: 20),
            ),
            FutureBuilder(
                future: _future(),
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  //해당 부분은 값을 아직 받아 오지 못했을때 실행되는 부분
                  if (snapshot.hasData == false) {
                    return CircularProgressIndicator(); // 로딩 구현
                  }
                  //에러 발생 시 반환 부분
                  else if (snapshot.hasError) {
                    return Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        'Error: ${snapshot.error}',
                        style: TextStyle(fontSize: 15),
                      ),
                    );
                  }
                  // 값을 정상적으로 받아오게 되면 다음 부분을 실행
                  else {
                    return Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        snapshot.data.toString(),
                        style: TextStyle(fontSize: 15),
                      ),
                    );
                  }
                })
          ],
        ),
      ),
    );
  }

  Future<String> _future() async {
    await Future.delayed(Duration(seconds: 2));
    return 'Call Value';
  }
}

profile
I want to become a versatile freelancer programmer💻

0개의 댓글