티스토리 뷰

State

우선 state란 무엇일까요?

공식 문서에서는

State is information that (1) can be read synchronously when the widget is built and (2) might change during the lifetime of the widget 라고 하네요

정말 간단하게 상태라고 할 수 있을 것 같아요.

지금 현상태는 색깔이 빨강이야
혹은, 지금 현상태는 isDone이 True야 같은 예가 있겠네요

flutter의 위젯은 이러한 state와 관련된 위젯이 두 개 있습니다.

StatelessWidget 과 StatefulWidget

https://i.stack.imgur.com/eQ688.png

출처: https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps/

 

두 위젯에서 공통적으로 해당하는 input data는 뭐가 있을까요?

Text("Hello")에서 "Hello"라는 string이 Text 위젯의 input data가 됩니다.

그러면 internal state는 뭐가 있을까요? 지금 만들고 있는 앱에서는 questionIndex 이 되겠죠? "지금 보여줘야 하는 퀴즈 문제의 순서"를 의미하는 하나의 state 즉 상태입니다. 그리고 지금 questionIndex += 1; 을 이용하여 그 상태의 값을 변할 수도 있는 거죠!

그래서 stateless위젯인 MyApp을 stateful위젯으로 바꿔줘야 합니다.

stateful 위젯으로 바꾸기

다행히 IDE에서 제공하는 기능으로 쉽게 바꿀 수 있습니다.

VS code에서는 StatelessWidget 을 클릭해주고 cmd + . 을 눌러주시면 됩니다 (안드로이드 스튜디오에서는 option + enter)

IDE가 클래스를 두 개 만들어줬어요

하나는 StatefulWidget를 상속받고, 하나는 State를 상속받네요

그런데 클래스가 두 개인 이유는 뭘까요?

지금 MyApp위젯은 다시 그려질 수 있습니다. 그런데 build를 할 때마다 state가 초기화되는 것을 방지하기 위해 분리를 한 겁니다.

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var questions = [
    "가장 좋아하는 색깔은 무엇인가요?",
    "가장 좋아하는 과일은 무엇인가요?",
  ];

  var questionIndex = 0;

  void answerQuestion() {
    setState(() {
      questionIndex += 1;
    });
    print(questionIndex);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("퀴즈 앱"),
        ),
        body: Column(
          children: [
            Text(questions[questionIndex]),
            RaisedButton(
              onPressed: answerQuestion,
              child: Text("빨강"),
            ),
            RaisedButton(
              onPressed: answerQuestion,
              child: Text("파랑"),
            ),
            RaisedButton(
              onPressed: answerQuestion,
              child: Text("검정"),
            ),
          ],
        ),
      ),
    );
  }
}

그런데 이렇게 코드를 바꾸고 실행해도 여전히 질문은 바뀌지 않는데요

플러터한테 다시 그려줘!라고 해줘야 합니다

void answerQuestion() {
    setState(() {
      questionIndex += 1;
    });
    print(questionIndex);
  }

핫 릴로드를 해주고 선택지 버튼을 눌러보면 ! 이제는 잘 넘어가지네요!

** 주의 **

여기서 한번 더 누르면 에러가 뜨는데 예외처리는 나중에 다시 한번 해줄게요!

 

아직은 처음이라서 자세히 다루지는 않았지만. stateless 하고 stateful에 대하여 더 자세히 알고 싶으면 여기를 참고하시면 됩니다.

private

현재 questions, questionIndex, answerQuestion 모두 외부에서 접근을 할 필요가 없으므로 pirvate로 바꿔줄게요

Dart 공식 문서를 살펴보면:

Unlike Java, Dart doesn’t have the keywords public, protected, and private. If an identifier starts with an underscore _, it’s private to its library.

dart에서는 일반적인 프로그래밍 언어에서 존재하는 public private와 같은 키워드가 없습니다

대신에 변 수명 앞에 _를 붙여주면 private가 됩니다.

IDE의 rename 기능을 이용하면 자동으로 다 찾아서 바꿔줍니다!

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함