일모도원(日暮途遠) 개발자

[Flutter개발] showModalBottomSheet에서 setState를 사용할수 없을때. 본문

Flutter/Flutter개발

[Flutter개발] showModalBottomSheet에서 setState를 사용할수 없을때.

달님개발자 2023. 11. 5. 18:19

StatefulWidget내에서가 아니라 다른 Dart파일의 일반 함수안에서 showModalBottomSheet를 실행시키는데, 스위치를 변경할 일이 있어서 setState를 쓰니까, setState가 없다고 나온다.

 

//A.dart파일의 Widget build(BuildContext context) 안에서 아래처럼 호출
showMyBottomSheet(context: context);

// B.dart파일 
void showMyBottomSheet({required BuildContext context}) {
  var isOption = true;
  showModalBottomSheet(
    context: context,
    builder: (BuildContext context) {
      return SizedBox(
          height: 300,
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ListTile(
                  title: const Text('Option 1'),
                  onTap: () {

                  },
                  trailing: CupertinoSwitch(
                    value: isOption,
                    onChanged: (value) {
                      //setState(() {
                        isOption = value;
                      //});
                    },
                  ),
                ),
              ],
            ),
          ));
    },
  );
}

 

이럴때는 StatefulBuilder를 사용하자. 원래의 return문을 아래처럼 StatefulBuilder와 builder로 잘 감싸야한다.

return StatefulBuilder(
  builder: (BuildContext context, void Function(void Function()) setState) {
    return SizedBox(
void showMyBottomSheet({required BuildContext context}) {
  var isOption = true;
  showModalBottomSheet(
    context: context,
    builder: (BuildContext context) {
      return StatefulBuilder(
        builder: (BuildContext context, void Function(void Function()) setState) {
          return SizedBox(
              height: 300,
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    ListTile(
                      title: const Text('Option 1'),
                      onTap: () {},
                      trailing: CupertinoSwitch(
                        value: isOption,
                        onChanged: (value) {
                          setState(() {
                            isOption = value;
                          });
                        },
                      ),
                    ),
                  ],
                ),
              ));
        },
      );
    },
  );
}