Skip to content

Commit

Permalink
fix: force lazyStateGetterSettter dependents to rebuild on state chan…
Browse files Browse the repository at this point in the history
…ge (#34)

Also fixes #32
  • Loading branch information
GregoryConrad authored Dec 24, 2023
1 parent b39cd67 commit 42d37d1
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
9 changes: 8 additions & 1 deletion packages/rearch/lib/src/side_effects.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ extension BuiltinSideEffects on SideEffectRegistrar {
/// see https://react.dev/reference/react/useState
(T Function(), void Function(T)) lazyStateGetterSetter<T>(T Function() init) {
// We use register directly to keep the same setter function across rebuilds
return use.register((api) {
// (but we need to return a new getter on each build, see below for more)
final (getter, setter) = use.register((api) {
var state = init();

T getter() => state;
Expand All @@ -60,6 +61,12 @@ extension BuiltinSideEffects on SideEffectRegistrar {

return (getter, setter);
});

// We *MUST* return a new getter function here,
// which we do simply by making a new closure. See here for why:
// https://github.com/GregoryConrad/rearch-dart/issues/32#issuecomment-1868399873
// ignore: unnecessary_lambdas
return (() => getter(), setter);
}

/// Side effect that provides a way for capsules to contain some state.
Expand Down
11 changes: 11 additions & 0 deletions packages/rearch/test/side_effects_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ import 'package:test/test.dart';
import 'util.dart';

void main() {
test('stateGetterSetter dependents should rebuild when state updated', () {
(int Function(), void Function(int)) stateCapsule(CapsuleHandle use) =>
use.stateGetterSetter(0);
int currStateCapsule(CapsuleHandle use) => use(stateCapsule).$1();

final container = useContainer();
expect(container.read(currStateCapsule), equals(0));
container.read(stateCapsule).$2(1);
expect(container.read(currStateCapsule), equals(1));
});

test('invalidatableFuture', () async {
var shouldError = false;

Expand Down

0 comments on commit 42d37d1

Please sign in to comment.