질문 제목:
원치 않는 위젯 빌드를 처리하는 방법은 무엇입니까?
질문 내용:
여러 가지 이유로
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
},
);
}
}
나는 이것을 이미 알고 있다. 나는 재건축을 최적화하고 싶어서여기 에 왔습니다.
자식도 강제로 빌드하지 않고 다시 빌드할 수 있는 위젯을 만드는 것도 가능합니다.위젯의 인스턴스가 동일하게 유지되는 경우 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
있지만 핫 리로드 기능을 중단하므로 덜 권장됩니다.
'expert' 카테고리의 다른 글
정의되지 않은 클래스 'FirebaseUser' (0) | 2023.01.24 |
---|---|
Dart null-safety로 마이그레이션한 후 "수신자가 null일 수 있기 때문에 연산자를 무조건적으로 호출할 수 없습니다" 오류 (0) | 2023.01.24 |
NoSuchMethod 오류란 무엇이며 어떻게 수정합니까? (0) | 2023.01.24 |
Flutter 앱 화면에서 서버의 응답을 표시하는 방법은 무엇입니까? (0) | 2023.01.24 |
Flutter를 사용하여 서버 API의 데이터가 Listview에 표시되지 않습니다. (0) | 2023.01.24 |
댓글