빌드 방법은 그것이 있어야하는 방식으로 설계되어 부작용없이 / 순수 . 많은 외부 요소가 다음과 같은 새 위젯 빌드를 트리거 할 수 있기 때문입니다.
- 루트 팝 / 푸시
- 키보드 모양 또는 방향 변경으로 인한 화면 크기 조정
- 부모 위젯이 자식을 재생성
- 위젯이 의존하는 InheritedWidget (
Class.of(context)
패턴) 변경
이는 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
},
);
}
}
나는 이것을 이미 알고있다. 나는 때문에 여기 온 진짜 최적화 재 구축하려는
또한 자식을 만들지 않고도 위젯을 다시 작성할 수 있습니다.
위젯 인스턴스가 동일하게 유지되는 경우 Flutter는 의도적으로 어린이를 재건하지 않습니다. 불필요한 재 빌드를 방지하기 위해 위젯 트리의 일부를 캐시 할 수 있음을 의미합니다.
가장 쉬운 방법은 다트 const
생성자 를 사용하는 것입니다 .
@override
Widget build(BuildContext context) {
return const DecoratedBox(
decoration: BoxDecoration(),
child: Text("Hello World"),
);
}
이 const
키워드 덕분에 DecoratedBox
빌드가 수백 번 호출 되더라도 인스턴스 는 동일하게 유지됩니다.
그러나 동일한 결과를 수동으로 얻을 수 있습니다.
@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,
],
);
},
);
}
이 예제에서 StreamBuilder에 새 값이 통보 subtree
되면 StreamBuilder / Column이 수행하더라도 다시 작성하지 않습니다. 폐쇄 덕분에 인스턴스가 MyWidget
변경되지 않았기 때문에 발생합니다 .
이 패턴은 애니메이션에서 많이 사용됩니다. 일반적인 용도 AnimatedBuilder
는와 같은 모든 전환 AlignTransition
입니다.
subtree
핫 리로드 기능을 중단하므로 권장하지 않지만 클래스의 필드에 저장할 수도 있습니다 .