원치 않는 위젯 빌드를 처리하는 방법은 무엇입니까?
여러 가지 이유로 때때로 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
'IT Share you' 카테고리의 다른 글
반복 필드에 할당하는 방법은 무엇입니까? (0) | 2020.12.04 |
---|---|
ES6 템플릿 리터럴 대 연결 문자열 (0) | 2020.12.04 |
명령 줄과 웹 서버 호출을 구별하는 방법은 무엇입니까? (0) | 2020.12.04 |
Android 색상 선택기 (0) | 2020.12.04 |
Left shifting with a negative shift count (0) | 2020.12.04 |