IT Share you

원치 않는 위젯 빌드를 처리하는 방법은 무엇입니까?

shareyou 2020. 12. 4. 21:28
반응형

원치 않는 위젯 빌드를 처리하는 방법은 무엇입니까?


여러 가지 이유로 때때로 build내 위젯 메서드가 다시 호출됩니다.

부모가 업데이트했기 때문에 발생한다는 것을 알고 있습니다. 그러나 이것은 원치 않는 결과를 초래합니다. 문제를 일으키는 일반적인 상황은 FutureBuilder다음과 같은 방법으로 사용할 때입니다 .

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: httpCall(),
    builder: (context, snapshot) {
      // create some layout here
    },
  );
}

이 예에서 빌드 메소드가 다시 호출되면 다른 http 요청이 트리거됩니다. 바람직하지 않습니다.

이를 고려하여 원치 않는 빌드를 처리하는 방법은 무엇입니까? 빌드 호출을 방지 할 수있는 방법이 있습니까?


빌드 방법은 그것이 있어야하는 방식으로 설계되어 부작용없이 / 순수 . 많은 외부 요인이 다음과 같은 새 위젯 빌드를 트리거 할 수 있기 때문입니다.

  • 인 / 아웃 애니메이션을위한 경로 팝 / 푸시
  • 일반적으로 키보드 모양 또는 방향 변경으로 인한 화면 크기 조정
  • 부모 위젯이 자식을 다시 생성했습니다.
  • 위젯이 ( Class.of(context)패턴) 변경 에 의존하는 InheritedWidget

다음은이 수단 build방법은해야 되지 는 HTTP 호출을 트리거 또는 상태를 수정 .


이것이 질문과 어떤 관련이 있습니까?

직면하고있는 문제는 빌드 방법에 부작용이 있거나 순수하지 않아 불필요한 빌드 호출이 번거 롭다는 것입니다.

빌드 호출을 방지하는 대신, 영향없이 언제든지 호출 할 수 있도록 빌드 메서드를 순수하게 만들어야합니다.

예제의 경우 위젯을로 변환 한 StatefulWidget다음 에 대한 HTTP 호출을 추출 initState합니다 State.

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  Future<int> future;

  @override
  void initState() {
    future = Future.value(42);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: future,
      builder: (context, snapshot) {
        // create some layout here
      },
    );
  }
}

  • 또한 자식도 빌드하지 않고 재 빌드 할 수있는 위젯을 만들 수도 있습니다.

When the instance of a widget stays the same; Flutter purposefully won't rebuild children. It implies that you can cache parts of your widget tree to prevent unnecessary rebuilds.

The easiest way is to use dart const constructors:

@override
Widget build(BuildContext context) {
  return const DecoratedBox(
    decoration: BoxDecoration(),
    child: Text("Hello World"),
  );
}

Thanks to that const keyword, the instance of DecoratedBox will stay the same even if build were called hundreds of times.

But you can achieve the same result manually:

@override
Widget build(BuildContext context) {
  final subtree = MyWidget(
    child: Text("Hello World")
  );

  return StreamBuilder<String>(
    stream: stream,
    initialData: "Foo",
    builder: (context, snapshot) {
      return Column(
        children: <Widget>[
          Text(snapshot.data),
          subtree,
        ],
      );
    },
  );
}

In this example when StreamBuilder is notified of new values, subtree won't rebuild even if the StreamBuilder/Column do. It happens because thanks to the closure, the instance of MyWidget didn't change.

This pattern is used a lot in animations. Typical users are AnimatedBuilder and all *Transition such as AlignTransition.

You could also store subtree into a field of your class, although less recommended as it breaks hot-reload.

참고URL : https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build

반응형