Flutter Stateful Widget 라이프 사이클 - 4. build

플랙트·2021년 4월 4일
0

지난 글에서는 initState에 대해서 살펴봤다. 이번 글에서는 build에 대해서 살펴볼 것이다.

아래는 대표적인 Stateful Widget인 체크박스 위젯의 build 함수 코드이다.

  
  Widget build(BuildContext context) {
    assert(debugCheckHasMaterial(context));
    final ThemeData themeData = Theme.of(context);
    Size size;
    switch (widget.materialTapTargetSize ?? themeData.materialTapTargetSize) {
      case MaterialTapTargetSize.padded:
        size = const Size(2 * kRadialReactionRadius + 8.0, 2 * kRadialReactionRadius + 8.0);
        break;
      case MaterialTapTargetSize.shrinkWrap:
        size = const Size(2 * kRadialReactionRadius, 2 * kRadialReactionRadius);
        break;
    }
    size += (widget.visualDensity ?? themeData.visualDensity).baseSizeAdjustment;
    final BoxConstraints additionalConstraints = BoxConstraints.tight(size);
    final MouseCursor effectiveMouseCursor = MaterialStateProperty.resolveAs<MouseCursor>(
      widget.mouseCursor ?? MaterialStateMouseCursor.clickable,
      <MaterialState>{
        if (!enabled) MaterialState.disabled,
        if (_hovering) MaterialState.hovered,
        if (_focused) MaterialState.focused,
        if (widget.tristate || widget.value) MaterialState.selected,
      },
    );

    return FocusableActionDetector(
      actions: _actionMap,
      focusNode: widget.focusNode,
      autofocus: widget.autofocus,
      enabled: enabled,
      onShowFocusHighlight: _handleFocusHighlightChanged,
      onShowHoverHighlight: _handleHoverChanged,
      mouseCursor: effectiveMouseCursor,
      child: Builder(
        builder: (BuildContext context) {
          return _CheckboxRenderObjectWidget(
            value: widget.value,
            tristate: widget.tristate,
            activeColor: widget.activeColor ?? themeData.toggleableActiveColor,
            checkColor: widget.checkColor ?? const Color(0xFFFFFFFF),
            inactiveColor: enabled ? themeData.unselectedWidgetColor : themeData.disabledColor,
            focusColor: widget.focusColor ?? themeData.focusColor,
            hoverColor: widget.hoverColor ?? themeData.hoverColor,
            onChanged: widget.onChanged,
            additionalConstraints: additionalConstraints,
            vsync: this,
            hasFocus: _focused,
            hovering: _hovering,
          );
        },
      ),
    );
  }

build 함수는 기본적으로 화면을 어떻게 그릴지를 담당하며, setState가 호출될때마다 호출되어진다. setState는 프레임워크에게 화면의 상태가 변경되어져야 함을 알리는 역할을 담당한다. setState는 화면에 실질적인 변경이 필요할때만 호출하면 된다. 예를 들어, 변경된 값을 화면에 반영하지 않고 파일에 쓰기만 할 경우에는 setState를 호출할 필요가 없다.

build함수에 로직을 넣을 때는 매우 주의해야한다. build함수에서 직접적으로 호출하는 로직은 위젯을 화면에 어떻게 그릴지 결정하는 로직만 넣는 것이 좋다. 만약 build 함수에 api를 호출하는 로직이 들어간다면 화면의 상태가 업데이트될때마다 api 호출이 발생하게 될 것이다. 또는 build함수에서 매우 오래걸리는 연산을 수행한다면 화면이 업데이트가 매우 느려지는 현상이 발생할 수도 있다.

build함수에서 직접적으로 setState를 하게 되면 오류가 발생한다. build-> setStae -> build -> setState -> ... 가 무한히 반복되기 때문이다. 다행히 flutter 프레임워크는 이를 감지하여 오류를 뱉어 준다.

profile
유용한 서비스에 관심이 많은 flutter 개발자입니다.

0개의 댓글