Flutter in Action - 상태 관리

Gavri·2022년 10월 10일

Flutter

목록 보기
4/14

상태관리

소개

상태 관리는 반응형 프로그래밍 프레임워크에서 빠질 수 없는 주제입니다. 상태는 누가 관리할까요?

  • 위젯은 자체가 상태를 관리
  • 위젯은 하위 위젯의 상태를 관리
  • 하이브리드 관리(상위 및 하위 위젯 모두 상태 관리)

위젯 자체가 상태 관리

class TapboxA extends StatefulWidget {
  TapboxA({Key? key}) : super(key: key);

  
  _TapboxAState createState() => _TapboxAState();
}

class _TapboxAState extends State<TapboxA> {
  bool _active = false;

  void _handleTap() {
    setState(() {
      _active = !_active;
    });
  }

  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            _active ? 'Active' : 'Inactive',
            style: TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: _active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }
}

상위 위젯은 하위 위젯의 상태를 관리합니다.

class ParentWidget extends StatefulWidget {
  
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  
  Widget build(BuildContext context) {
    return Container(
      child: TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

//------------------------- TapboxB ----------------------------------

class TapboxB extends StatelessWidget {
  TapboxB({Key? key, this.active: false, required this.onChanged})
      : super(key: key);

  final bool active;
  final ValueChanged<bool> onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            active ? 'Active' : 'Inactive',
            style: TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }
}

하이브리드 상태 관리

//---------------------------- ParentWidget ----------------------------

class ParentWidgetC extends StatefulWidget {
  
  _ParentWidgetCState createState() => _ParentWidgetCState();
}

class _ParentWidgetCState extends State<ParentWidgetC> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  
  Widget build(BuildContext context) {
    return Container(
      child: TapboxC(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

//----------------------------- TapboxC ------------------------------

class TapboxC extends StatefulWidget {
  TapboxC({Key? key, this.active: false, required this.onChanged})
      : super(key: key);

  final bool active;
  final ValueChanged<bool> onChanged;

  
  _TapboxCState createState() => _TapboxCState();
}

class _TapboxCState extends State<TapboxC> {
  bool _highlight = false;

  void _handleTapDown(TapDownDetails details) {
    setState(() {
      _highlight = true;
    });
  }

  void _handleTapUp(TapUpDetails details) {
    setState(() {
      _highlight = false;
    });
  }

  void _handleTapCancel() {
    setState(() {
      _highlight = false;
    });
  }

  void _handleTap() {
    widget.onChanged(!widget.active);
  }

  
  Widget build(BuildContext context) {
    // 在按下时添加绿色边框,当抬起时,取消高亮
    return GestureDetector(
      onTapDown: _handleTapDown, // 处理按下事件
      onTapUp: _handleTapUp, // 处理抬起事件
      onTap: _handleTap,
      onTapCancel: _handleTapCancel,
      child: Container(
        child: Center(
          child: Text(
            widget.active ? 'Active' : 'Inactive',
            style: TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
          border: _highlight
              ? Border.all(
                  color: Colors.teal[700],
                  width: 10.0,
                )
              : null,
        ),
      ),
    );
  }
}

글로벌 상태 관리

응용 프로그램의 상태를 구성 요소 간에 동기화를 해야 하는 경우 위 3가지 방법만으로는 어렵습니다.
이런 문제를 해결 하기 위한 방법을 알아 보도록 하겠습니다

  1. 전역 이벤트 버스를 구현하고 언어 상태 변경을 이벤트로 매핑한 다음 initStateAPP의 응용 프로그램 언어에 의존하는 구성 요소의 메서드에서 언어 변경 이벤트를 구독합니다. 사용자가 설정 페이지에서 언어를 전환하면 언어 변경 이벤트를 게시하고 이 이벤트를 구독하는 구성 요소는 알림을 수신합니다.알림을 받은 후 setState(...)메서드를 호출하여 build자체를 다시 시작할 수 있습니다.
  2. Provider, Redux와 같은 상태 관리 전용 패키지를 사용하면 독자가 pub에서 세부 정보를 볼 수 있습니다.
profile
모든건 기록으로

0개의 댓글