Closed subzero911 closed 8 months ago
I'm still struggling with this behaviour.
If I wrap the whole TaskListView into Observer, it's working
If I remove .toList()
, then no errors are logged, but the button stops working (but in theory it should log “no observables found”, as we do nothing on todaysTodoTasksWindow
and pass it to the child parameter - it should be out of immediate context).
If I wrap the root of TaskListView widget into Observer, it won't work:
It either glitches when I derive a computed from computed (endReached
derived from todaysTodoTasksSource
which is derived from _todaysTasks
), or when I put an Observer into Observer.
But I tested it on a simple "counter" app and can't find the bug.
@subzero911 Can you give me the code to reproduce it?
I can't share the whole project as it's under NDA, but I can share some files which are related to error:
@subzero911 Shouldn't _offset
be observable
?
When showCollapseButton and endReached are changing, UI rebuilds successfully.
But if I wrap inner TextButton in additional Observer, for some reason it doesn't rebuild properly. Observer->Column->TaskListView->Column->Observer->Button
In this case, it seems to be because the computed used by the button is not changing properly. When the button is not wrapped in an observer, a rebuild occurs in the parent widget and it changes properly.
import 'package:mobx/mobx.dart';
import 'package:test/test.dart';
part 'nested_store.g.dart';
// ignore: library_private_types_in_public_api
class NestedStore = _NestedStore with _$NestedStore;
abstract class _NestedStore with Store {
@observable
ObservableList<int> list = ObservableList();
int offset = 0;
@computed
bool get endReached => list.length >= offset;
}
class NestedStore2 = _NestedStore2 with _$NestedStore2;
abstract class _NestedStore2 with Store {
@observable
ObservableList<int> list = ObservableList();
@observable
int offset = 0;
@computed
bool get endReached => list.length >= offset;
}
void main() {
test('offset', () {
final store = NestedStore();
var f;
reaction((p0) => store.endReached, (value) {
f = value;
});
store.offset = 1;
expect(f, null);
runInAction(() => store.list.add(1));
expect(f, null);
runInAction(() => store.list.add(1));
expect(f, null);
});
test('offset observable', () {
final store = NestedStore2();
var f;
reaction((p0) => store.endReached, (value) {
f = value;
});
store.offset = 1;
expect(f, false);
runInAction(() => store.list.add(1));
expect(f, true);
runInAction(() => store.list.add(1));
expect(f, true);
});
}
Yes, you were right, I forgot to mark _offset
as @observable
! That's why computed wasn't recalculated.
Thank you @amondnet ! I wrestled with it for a lot of time, and thought that there's some issue with MobX, but it was a problem on my side.
So I'll close the issue.
I encountered the strange behaviour when the Observer is not rebuilding. When I have the following structrure: Observer->Column->TaskListView->Column->Button (where TaskListView is a StatelessWidget)
When showCollapseButton and endReached are changing, UI rebuilds successfully.
But if I wrap inner TextButton in additional Observer, for some reason it doesn't rebuild properly. Observer->Column->TaskListView->Column->Observer->Button
It's always "show more" button which never turns to "collapse".
Computeds:
I don't know exactly how to create a minimal reproducible example. I found this behaviour in our project.