[이론] StatefulWidget (2) StatefulWidget 선언하기
들어가기 앞서...
이전 게시글 에는 StatelessWidget, StatefulWidget의 생명주기 및 흐름도를 공부했다.
이제는 실습을 할 차례이다. StatelessWidget으로 선언되어있는 코드를 StatefulWidget 으로 변경하도록 해보자!
주의 깊게 봐야하는 점...
StatefulWidget 에서는 Constructor 가 필요 없다고 이전 게시글에 말했는데, 그 이유를 본문에 적을 것이다!
StatefulWidget 을 만들기위해서는 신경 써야할 점을 밑에 적어놨다.
본문으로...
첫번째로 프로젝트에 화면 안 에다가 버튼 두개를 만드는 코드를 작성을 해놨다.
main.dart 에서 위젯 생성하기 버튼을 누르면, home_screen.dart에 HiomeScreen을 띄울수 있도록 코드를 작성해놨다.
HomeScreen 의 Widget build 함수에는 넓이 50, 길이 50 빨간색의 Container 하나가 있다.
HomeScreen 클래스를 보면, Color 라는 파라미터를 받고있고, 그 Color를 Container 안에 색으로 주입시켜주고있다.
순서는 HOmeScreen({color 값이 들어오고}) -> 위에 선언해둔 final Color color; -> build 함수의 Container 안에 color 순으로 되면서 색상이 변경이 된다.
// home_screen.dart
class HomeScreen extends StatelessWidget {
final Color color;
const HomeScreen({
required this.color,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: 50.0,
height: 50.0,
color: color,
);
}
}
현재 위에 코드는 StatelessWidget 으로 상속 되어있는데, 나는 이 코드를 StatefullWidget 으로 변경을 할 것이다.
StatefulWidget 은 클래스가 총 두개이다.
StatefulWidget 과 State 클래스!
밑의 코드는 간단하게 클래스를 StatefulWidget으로 만든 것이다.
클래스를 StatefulWidget 형태로로 만드는 방법은 간단하게 설명하겠다.
1. StatefulWidget 클래스와 State 클래스 를 각 한개를 만들어준다.
2. StatefulWidget 클래스에는 constructor 와 createState 함수를 만들어준다.
3. State 클래스의 뒤에는 State 를 extends 해주고 제너릭은 바인딩할 StatefulWidget클래스를 지정해준다.
4. State 클래스 안에 build 함수를 생성해준다.
5. State 클래스 안에서 상위 클래스인 StatefulWidget에 선언해둔 변수를 사용하고 싶으면 widget. 을 사용해서 불러오면 된다. (절대로! State 클래스 안에 constructor 를 만드는 일은 없어야한다. !! 절대로!)
class HomeScreen extends StatefulWidget{
// 1) 색깔 변수 선언
final Color color;
// 2) constructor 선언
const HomeScreen({
required this.color,
Key? key,
}) : super(key: key);
// 3)
@override
State<StatefulWidget> createState() {
return _HomeScreenState();
}
}
// 4)
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Container(
width: 50.0,
height:50.0,
// 5)
color: widget.color
)
}
}
1번 설명)
➡️ 색깔을 저장해둘 변수를 선언해둔 것이다.
2번 설명)
➡️ StatefulWidget 클래스에는 제일 먼저 생성되자마자 Constructor 함수가 실행이 된다. (이걸 모른다면 위의 그림을 보자! 그 이유는 색깔을 받아서 파라미터로 보내 build 함수를 실행 시켜줘야하기 때문이다.)
constructor함수 안에 파라미터로 받을 color 를 required 파라미터로 적어주자. 나머지는 이하 동일 하게 작성
3번 설명)
➡️ StatefulWidget 클래스에는 위의 그림에서 보듯이 createState 함수를 실행시켜줘야한다. 선언을 안해주면 클래스에서 빨간색 에러가 뜨니 까먹지 말자~
cereateState() 함수의 return 은 _HomeScreenState() 로 적어주었는데, 그 이유는?
StatefulWidget에 해당하는 HomeScreen 클래스는 외부에서 사용할 일이 있는데, _HomeScreenState() 인 State 같은 경우는 어차피 StatefulWidget 에 바인딩되어 붙어서 함께 가는 것이기때문에 외부에서는 State 만 불르지 못하게 하도록 _ (언더스코어) 로 privite 하게 작성을 해준것이다.
4번 설명)
➡️ State 클래스를 선언해 준 것이댜. State 클래스를 선언하는 방법은 그냥 뒤에 State 를 상속을 해주면 된다! State 는 특별하게 뒤에 제너릭을 만들어줘야한다. <> 제너릭 안에는 바인딩을 할 것을 넣어주면 된다.
5번 설명)
➡️ StatelessWidget 으로 선언을 했을떄는 하나의 클래스에서 가져오는 것이므로 color 를 파라미터로 가져와 변수선을 해서 바로 사용이 가능했다. 하지만 지금은 StatefulWidget으로 클래스와 State 클래스 두개이다. 우리가 color 코드가 필요한 곳은 State 클래스이다.
State 클래스는 StatefulWidget 클래스에서 파라미터를 받기 때문에 다른 클래스에서 파라미터를 받아 사용할 방법을 알고 있어야한다.
흔히 잘못 착각할 수 있는 것이! State 클래스에도 파라미터를 받을 수 있게 constructor 를 만들면 되는 것이 아니냐? 라는 것이 있는데 그렇게 하면 절대로 안된다.
그 이유는 State 클래스는 재사용 할것인데, Constructor 는 클래스가 생성 될떄만 불리기 떄문이다. Color 라는 파라미터는 HomeScreenState() 가 변경이 되지 않은 상태에서도 변경이 될수 가 있다.
예 ) 빨간색 HomeScreen 을 불렀는데 파란색으로 색깔을 바꾸면은 createState 는 다시 불리지 않는다. HomeScreenState 는 다시 생성하지 않는다. 그러므로 constructor 는 호출 되지 않는다! 근데 여기서 State 클래스 안에 변수 선언 해둔 color 가 constructor 의 color 를 가르킨다면? 변경을 해도 색깔이 변경이 되지 않는 상황이 일어난다.
그렇기 떄문에 State 클래스에는 Constructor 가 중요하지 않고, 사용하지 않는다는 것이다.
State 와 StatefulWidget 은 절대적으로 세트인것을 알아두면 쉽다.
그래서 간단하게 가져올 수 있는데, widget. 을 사용하면 State 클래스에서 StatefulWidget의 변수를 가져올 수 있다.
주의 해야할 점이 State<> 클래스에 제너릭으로 바인딩해야할 클래스를 적어둔 곳 기준으로 가기 때문에 확인해야 한다.
2번째 방법 기존 StatelessWidget을 StatefulWidget으로 바꾸는 방법!
Conver to StatefulWidget 버튼을 클릭하면 바로 생성된다.
미친 커맨드 ... 1번쨰 방법처럼 손으로 일일히 작성 안해도 된다.
위의 코드는 StatelessWidget 의 코드이다.
HomeScreen 클래스에서 option + enter 를 커맨드를 클릭하고 Convert to StatefulWidget 버튼이 나오며 저 버튼을 클릭하면 밑에 바로 생성되는 것을 볼 수 있다
세번째 방법 한번에 명령어로 StatefulWidget 코드 만들기
stful 하면 클래스가 자동으로 생긴다.
// 명령어 입력
stful
// 결과 - class 이름을 바로 지정하게끔 포커싱이 되어있다!
class extends StatefulWidget {
const ({Key? key}) : super(key: key);
@override
State<> createState() => _State();
}
class _State extends State<> {
@override
Widget build(BuildContext context) {
return Container();
}
}
끝으로...
- 커맨드를 사용해 StatelessWidget, StatefulWidget 서로 교차 변경 을 할 수 있다!
- StatefulWidget클래스 State 클래스 작성법을 알고 State 클래스에는 constructor 를 작성하면 안된다 라는것을 알았다!
- State 클래스에서 StatefulWidget 클래스에서 파라미터를 받아 사용하는 방법을 알았다!
꿀팁💡 StatelessWidget 명령어 하는 방법 💡
stless
꿀팁💡 StatefullWidget 명령어 하는 방법 💡
stful
꿀팁💡 StatelessWidget -> StatefullWidget 으로 변경하는 명령어 (반대로 가능!) 💡
StatelessWidget클래스에 포커싱 후 option + enter 클릭 후 convert to StatefulWidget 클릭
