diff --git a/.changeset/fresh-trams-joke.md b/.changeset/fresh-trams-joke.md new file mode 100644 index 000000000..f5e9593df --- /dev/null +++ b/.changeset/fresh-trams-joke.md @@ -0,0 +1,5 @@ +--- +'@tanstack/angular-form': patch +--- + +prevent full array re-renders in array mode diff --git a/docs/framework/angular/guides/arrays.md b/docs/framework/angular/guides/arrays.md index 9b1580257..742c62ba1 100644 --- a/docs/framework/angular/guides/arrays.md +++ b/docs/framework/angular/guides/arrays.md @@ -15,7 +15,7 @@ To use an array, you can use `field.api.state.value` on an array value: standalone: true, imports: [TanStackField], template: ` - +
@for (_ of people.api.state.value; track $index) { @@ -101,7 +101,7 @@ export class AppComponent { template: `
- +
@for (_ of people.api.state.value; track $index) {
- +
@for (_ of people.api.state.value; track $index) { { - return [ - state.meta, - Object.keys((state.value as unknown) ?? []).length, - ] - } - : undefined, - { - injector: this.injector, - }, + (state) => + isArrayMode + ? Object.keys((state.value as unknown) ?? []).length + : state.value, + injectorOpts, + ) + const reactiveIsTouched = injectStore( + this._api().store, + (state) => state.meta.isTouched, + injectorOpts, + ) + const reactiveIsBlurred = injectStore( + this._api().store, + (state) => state.meta.isBlurred, + injectorOpts, + ) + const reactiveIsDirty = injectStore( + this._api().store, + (state) => state.meta.isDirty, + injectorOpts, + ) + const reactiveErrorMap = injectStore( + this._api().store, + (state) => state.meta.errorMap, + injectorOpts, + ) + const reactiveErrorSourceMap = injectStore( + this._api().store, + (state) => state.meta.errorSourceMap, + injectorOpts, + ) + const reactiveIsValidating = injectStore( + this._api().store, + (state) => state.meta.isValidating, + injectorOpts, ) effect( () => { - // Load bearing change detection check - const _values = vals() + // Load bearing change detection check — read every reactive source so + // the effect runs whenever any of them change. + reactiveValue() + reactiveIsTouched() + reactiveIsBlurred() + reactiveIsDirty() + reactiveErrorMap() + reactiveErrorSourceMap() + reactiveIsValidating() this.cd.markForCheck() }, { injector: this.injector },