사전지식
provider의 context.selector(....)
는 selector에 등록된 변수의 값이 바뀌는지 tracking하고, 값이 바뀌면 해당 위젯을 rebuild하는 메소드이다.context.watch()
도 있지만 wathc는 해당 값 말고 같은 changeNotifier 안에 등록된 다른 값이 바뀌어도 rebuild가 일어나 selector를 사용하면 불필요한 rebuild를 줄일 수 있다.
문제상황
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building:
Tried to use context.select inside a SliverList/SliderGridView.
This is likely a mistake, as instead of rebuilding only the item that cares
about the selected value, this would rebuild the entire list/grid.
To fix, add a `Builder` or extract the content of `itemBuilder` in a separate widget:
```dart
ListView.builder(
itemBuilder: (context, index) {
return Builder(builder: (context) {
final todo = context.select((TodoList list) => list[index]);
return Text(todo.name);
});
},
);
```
'package:provider/src/inherited_provider.dart':
Failed assertion: line 247 pos 12: 'widget is! SliverWithKeepAliveWidget'
ListView.builder
안에서 직접 context.selector
를 사용해 해당 오류가 뜬걸로 보인다.
ListView.builder안에 직접 selector를 넣으면 ListView 전체가 rebuild가 일어나는 비효율적인 상황이 발생하므로 해당 오류를 던진 것으로 보인다.
해결 방법
친절하게도, flutter에서는 이번 오류 안에서 어떻게 해야할지를 알려준다.context.select
를 바로 ListView.builder안에 넣지 말고, 대신 Builder 위젯을 사용해 그 안에서 selector를 사용하는 방식으로 문제를 해결할 수 있을 것이다.
LIST