diff --git a/docs/framework/react/guides/custom-errors.md b/docs/framework/react/guides/custom-errors.md index 0ecb12a07..3a78ae528 100644 --- a/docs/framework/react/guides/custom-errors.md +++ b/docs/framework/react/guides/custom-errors.md @@ -5,7 +5,7 @@ title: Custom Errors TanStack Form provides complete flexibility in the types of error values you can return from validators. String errors are the most common and easy to work with, but the library allows you to return any type of value from your validators. -As a general rule, any truthy value is considered as an error and will mark the form or field as invalid, while falsy values (`false`, `undefined`, `null`, etc..) mean there is no error, the form or field is valid. +As a general rule, any truthy value is considered an error and will mark the form or field as invalid, while falsy values (`false`, `undefined`, `null`, etc.) mean there is no error, and the form or field is valid. ## Return String Values from Forms @@ -133,7 +133,7 @@ Display in UI: } ``` -in the example above it depends on the event error you want to display. +In the example above, the rendered message, code and styling depend on the event error you want to display. ### Arrays @@ -171,7 +171,7 @@ Display in UI: ## The `disableErrorFlat` Prop on Fields -By default, TanStack Form flattens errors from all validation sources (onChange, onBlur, onSubmit) into a single `errors` array. The `disableErrorFlat` prop preserves the error sources: +By default, TanStack Form flattens errors from all validation sources (`onChange`, `onBlur`, `onSubmit`) into a single `errors` array. The `disableErrorFlat` prop preserves the error sources: ```tsx { @@ -31,11 +31,12 @@ const form = useForm({ }) ``` -> By default `onDynamic` is not called, so you need to pass `revalidateLogic()` to the `validationLogic` option of `useForm`. +> [!IMPORTANT] +> By default, `onDynamic` is not called; therefore you must pass `revalidateLogic()` to the `validationLogic` option of `useForm`. ## Revalidation Options -`revalidateLogic` allows you to specify when validation should be run and change the validation rules dynamically based on the current submission state of the form. +`revalidateLogic` allows you to specify when validation should be run and to change the validation rules dynamically based on the current submission state of the form. It takes two arguments: @@ -64,7 +65,7 @@ const form = useForm({ ## Accessing Errors -Just as you might access errors from an `onChange` or `onBlur` validation, you can access the errors from the `onDynamic` validation function using the `form.state.errorMap` object. +Just as you might access errors from an `onChange` or `onBlur` validation, you can access errors from the `onDynamic` validation function using the `form.state.errorMap` object. ```tsx function App() { @@ -177,7 +178,7 @@ function App() { ### Async Validation -Async validation can also be used with `onDynamic` just like with other validation logic. You can even debounce the async validation to avoid excessive calls. +Async validation can also be used with `onDynamicAsync` just like with other validation logic. You can even debounce the async validation to avoid excessive calls. ```tsx const form = useForm({ diff --git a/docs/framework/react/guides/form-composition.md b/docs/framework/react/guides/form-composition.md index f30102237..e334a82b4 100644 --- a/docs/framework/react/guides/form-composition.md +++ b/docs/framework/react/guides/form-composition.md @@ -3,7 +3,7 @@ id: form-composition title: Form Composition --- -A common criticism of TanStack Form is its verbosity out-of-the-box. While this _can_ be useful for educational purposes - helping enforce understanding our APIs - it's not ideal in production use cases. +A common criticism of TanStack Form is that it is verbose out-of-the-box. While this verbosity _can_ be useful for educational purposes - helping to enforce understanding of our APIs - it's not ideal in production use cases. As a result, while `form.Field` enables the most powerful and flexible usage of TanStack Form, we provide APIs that wrap it and make your application code less verbose. @@ -103,7 +103,7 @@ function App() { } ``` -This not only allows you to reuse the UI of your shared component, but retains the type-safety you'd expect from TanStack Form: Typo `name` and get a TypeScript error. +This not only allows you to reuse the UI of your shared component, but retains the type-safety you'd expect from TanStack Form: Mistyping `name` will result in a TypeScript error. #### A note on performance @@ -162,7 +162,7 @@ function App() { ## Breaking big forms into smaller pieces -Sometimes forms get very large; it's just how it goes sometimes. While TanStack Form supports large forms well, it's never fun to work with hundreds or thousands of lines of code long files. +Sometimes forms get very large; it's just how it goes sometimes. While TanStack Form supports large forms well, it's never fun to work with hundreds or thousands of lines of code in single files. To solve this, we support breaking forms into smaller pieces using the `withForm` higher-order component. diff --git a/docs/framework/react/guides/linked-fields.md b/docs/framework/react/guides/linked-fields.md index c6065afe8..75c7f98f2 100644 --- a/docs/framework/react/guides/linked-fields.md +++ b/docs/framework/react/guides/linked-fields.md @@ -3,21 +3,19 @@ id: linked-fields title: Link Two Form Fields Together --- -You may find yourself needing to link two fields together; when one is validated as another field's value has changed. -One such usage is when you have both a `password` and `confirm_password` field, -where you want to `confirm_password` to error out when `password`'s value does not match; -regardless of which field triggered the value change. +You may find yourself needing to link two fields together, such that one is validated when another's value has changed. +One such use case is when you have both a `password` and a `confirm_password` field. +Here, you want the `confirm_password` field to error out if its value doesn't match that of the `password` field, regardless of which field triggered the value change. -Imagine the following userflow: +Imagine the following user flow: -- User updates confirm password field. -- User updates the non-confirm password field. +- User updates the `confirm_password` field. +- User updates the `password` field. -In this example, the form will still have errors present, -as the "confirm password" field validation has not been re-ran to mark as accepted. +In this example, the form will still have errors present because the `confirm_password` field's validation has not been re-run to mark the field as valid. -To solve this, we need to make sure that the "confirm password" validation is re-run when the password field is updated. -To do this, you can add a `onChangeListenTo` property to the `confirm_password` field. +To solve this, you need to make sure that the `confirm_password` field's validation is re-run when the `password` field is updated. +To do this, you can add an `onChangeListenTo` prop to the `confirm_password` field. ```tsx function App() { @@ -74,4 +72,4 @@ function App() { } ``` -This similarly works with `onBlurListenTo` property, which will re-run the validation when the field is blurred. +This is similar to the `onBlurListenTo` prop, which re-runs the validation when the linked field is blurred. diff --git a/docs/framework/react/guides/listeners.md b/docs/framework/react/guides/listeners.md index d57cd8c87..b5f765d11 100644 --- a/docs/framework/react/guides/listeners.md +++ b/docs/framework/react/guides/listeners.md @@ -11,7 +11,7 @@ Imagine the following user flow: - User then selects a province from another drop-down. - User changes the selected country to a different one. -In this example, when the user changes the country, the selected province needs to be reset as it's no longer valid. With the listener API, we can subscribe to the onChange event and dispatch a reset to the field "province" when the listener is fired. +In this example, when the user changes the country, the selected province needs to be reset as it's no longer valid. With the listener API, we can subscribe to the `onChange` event and dispatch a reset to the "province" field when the listener is fired. Events that can be "listened" to are: @@ -94,7 +94,7 @@ We enable an easy method for debouncing your listeners by adding a `onChangeDebo At a higher level, listeners are also available at the form level, allowing you access to the `onMount` and `onSubmit` events, and having `onChange` and `onBlur` propagated to all the form's children. Form-level listeners can also be debounced in the same way as previously discussed. -`onMount` and `onSubmit` listeners have to following props: +`onMount` and `onSubmit` listeners have the following parameters: - `formApi` diff --git a/docs/framework/react/guides/reactivity.md b/docs/framework/react/guides/reactivity.md index 479facf44..f5537923f 100644 --- a/docs/framework/react/guides/reactivity.md +++ b/docs/framework/react/guides/reactivity.md @@ -3,7 +3,7 @@ id: reactivity title: Reactivity --- -Tanstack Form doesn't cause re-renders when interacting with the form. So you might find yourself trying to use a form or field state value without success. +Tanstack Form doesn't cause re-renders when interacting with the form. So, you might find yourself trying to use a form or field state value without success. If you would like to access reactive values, you will need to subscribe to them using one of two methods: `useStore` or the `form.Subscribe` component. @@ -13,7 +13,7 @@ Some uses for these subscriptions are rendering up-to-date field values, determi ## useStore -The `useStore` hook is perfect when you need to access form values within the logic of your component. `useStore` takes two parameters. First, the form store. Second a selector to fine tune the piece of the form you wish to subscribe to. +The `useStore` hook is perfect when you need to access form values within the logic of your component. `useStore` takes two parameters. First, the form store. Second, a selector to specify the piece of the form you wish to subscribe to. ```tsx const firstName = useStore(form.store, (state) => state.values.firstName) @@ -28,7 +28,7 @@ While it IS possible to omit the selector, resist the urge as omitting it would ## form.Subscribe -The `form.Subscribe` component is best suited when you need to react to something within the UI of your component. For example, showing or hiding ui based on the value of a form field. +The `form.Subscribe` component is best suited when you need to react to something within the UI of your component. For example, showing or hiding UI based on the value of a form field. ```tsx The `form.Subscribe` component doesn't trigger component-level re-renders. Anytime the value subscribed to changes, only the `form.Subscribe` component re-renders. -The choice between whether to use `useStore` or `form.Subscribe` mainly boils down to that if it's rendered in the ui, reach for `form.Subscribe` for its optimizations perks, and if you need the reactivity within the logic, then `useStore` is the choice to make. +The choice between whether to use `useStore` or `form.Subscribe` mainly boils down to your use case. If you're aiming for direct UI updates based on form state, use `form.Subscribe` for its optimization perks. And if you need the reactivity within the logic, then `useStore` is the better choice. diff --git a/docs/framework/react/guides/submission-handling.md b/docs/framework/react/guides/submission-handling.md index a7fe65ca7..7198217be 100644 --- a/docs/framework/react/guides/submission-handling.md +++ b/docs/framework/react/guides/submission-handling.md @@ -5,7 +5,7 @@ title: Submission handling ## Passing additional data to submission handling -You may have multiple types of submission behaviour, for example, going back to another page or staying on the form. +You may have multiple types of submission behaviour, for example, going back to the previous page or staying on the form. You can accomplish this by specifying the `onSubmitMeta` property. This meta data will be passed to the `onSubmit` function. > Note: if `form.handleSubmit()` is called without metadata, it will use the provided default. diff --git a/docs/framework/react/guides/validation.md b/docs/framework/react/guides/validation.md index 9ae0f061a..969a9fbfa 100644 --- a/docs/framework/react/guides/validation.md +++ b/docs/framework/react/guides/validation.md @@ -3,15 +3,15 @@ id: form-validation title: Form and Field Validation --- -At the core of TanStack Form's functionalities is the concept of validation. TanStack Form makes validation highly customizable: +At the core of TanStack Form's functionality is the concept of validation. TanStack Form makes validation highly customizable: -- You can control when to perform the validation (on change, on input, on blur, on submit...) -- Validation rules can be defined at the field level or at the form level +- You can control when to perform the validation (on change, on input, on blur, on submit, etc.) +- Validation rules can be defined at the field-level or at the form-level - Validation can be synchronous or asynchronous (for example, as a result of an API call) ## When is validation performed? -It's up to you! The `` component accepts some callbacks as props such as `onChange` or `onBlur`. Those callbacks are passed the current value of the field, as well as the fieldAPI object, so that you can perform the validation. If you find a validation error, simply return the error message as string and it will be available in `field.state.meta.errors`. +It's up to you! The `` component accepts some callbacks as props such as `onChange` or `onBlur`. Those callbacks are passed the current value of the field, as well as the `fieldApi` object, so that you can perform the validation. If you find a validation error, simply return the error message as a string, and it will be available in `field.state.meta.errors`. Here is an example: @@ -72,7 +72,7 @@ In the example above, the validation is done at each keystroke (`onChange`). If, ``` -So you can control when the validation is done by implementing the desired callback. You can even perform different pieces of validation at different times: +So, you can control when the validation is done by implementing the desired callback. You can even perform different pieces of validation at different times: ```tsx ``` -In the example above, we are validating different things on the same field at different times (at each keystroke and when blurring the field). Since `field.state.meta.errors` is an array, all the relevant errors at a given time are displayed. You can also use `field.state.meta.errorMap` to get errors based on _when_ the validation was done (onChange, onBlur etc...). More info about displaying errors below. +In the example above, we are validating different things on the same field at different times (at each keystroke and when blurring the field). Since `field.state.meta.errors` is an array, all the relevant errors at a given time are displayed. You can also use `field.state.meta.errorMap` to get errors based on _when_ the validation was done (onChange, onBlur, etc.). More information about displaying errors is below. ## Displaying Errors @@ -152,7 +152,7 @@ Or use the `errorMap` property to access the specific error you're looking for: ``` -It's worth mentioning that our `errors` array and the `errorMap` matches the types returned by the validators. This means that: +It's worth mentioning that our `errors` array and the `errorMap` match the types returned by the validators. This means that: ```tsx ``` -## Validation at field level vs at form level +## Validation at field-level vs at form-level -As shown above, each `` accepts its own validation rules via the `onChange`, `onBlur` etc... callbacks. It is also possible to define validation rules at the form level (as opposed to field by field) by passing similar callbacks to the `useForm()` hook. +As shown above, each `` accepts its own validation rules via the callbacks such as `onChange` and `onBlur`. It is also possible to define validation rules at the form-level (as opposed to field-by-field) by passing similar callbacks to the `useForm()` hook. Example: @@ -200,8 +200,8 @@ export default function App() { }, }) - // Subscribe to the form's error map so that updates to it will render - // alternately, you can use `form.Subscribe` + // Subscribe to the form's `errorMap` so that updates to it will cause re-renders + // Alternatively, you can use `form.Subscribe` const formErrorMap = useStore(form.store, (state) => state.errorMap) return ( @@ -329,11 +329,11 @@ export default function App() { > ) > ``` > -> Will only show `'Must be odd!` even if the 'Too young!' error is returned by the form-level validation. +> Will only show `'Must be odd!'` even if the 'Too young!' error is returned by the form-level validation. ## Asynchronous Functional Validation -While we suspect most validations will be synchronous, there are many instances where a network call or some other async operation would be useful to validate against. +While we suspect most validation will be synchronous, there are many instances where a network call or some other async operation would be useful to validate against. To do this, we have dedicated `onChangeAsync`, `onBlurAsync`, and other methods that can be used to validate against: @@ -365,7 +365,7 @@ To do this, we have dedicated `onChangeAsync`, `onBlurAsync`, and other methods ``` -Synchronous and Asynchronous validations can coexist. For example, it is possible to define both `onBlur` and `onBlurAsync` on the same field: +Synchronous and asynchronous validators can coexist. For example, it is possible to define both `onBlur` and `onBlurAsync` on the same field: ```tsx ``` -The synchronous validation method (`onBlur`) is run first and the asynchronous method (`onBlurAsync`) is only run if the synchronous one (`onBlur`) succeeds. To change this behaviour, set the `asyncAlways` option to `true`, and the async method will be run regardless of the result of the sync method. +The synchronous validation method (`onBlur`) is run first, and the asynchronous method (`onBlurAsync`) is only run if the synchronous one (`onBlur`) succeeds. To change this behaviour, set the `asyncAlways` option to `true`, and the async method will be run regardless of the result of the sync method. ### Built-in Debouncing -While async calls are the way to go when validating against the database, running a network request on every keystroke is a good way to DDOS your database. +While async calls are the way to go when validating against the database, running a network request on every keystroke is a good way to DDoS your database. Instead, we enable an easy method for debouncing your `async` calls by adding a single property: @@ -441,11 +441,11 @@ This will debounce every async call with a 500ms delay. You can even override th /> ``` -This will run `onChangeAsync` every 1500ms while `onBlurAsync` will run every 500ms. +This will run `onChangeAsync` every 1500ms, whereas `onBlurAsync` will run every 500ms. ## Validation through Schema Libraries -While functions provide more flexibility and customization over your validation, they can be a bit verbose. To help solve this, there are libraries that provide schema-based validation to make shorthand and type-strict validation substantially easier. You can also define a single schema for your entire form and pass it to the form level, errors will be automatically propagated to the fields. +While functions provide more flexibility and customization over your validation, they can be a bit verbose. To help solve this, there are libraries that provide schema-based validation to make shorthand and type-strict validation substantially easier. You can also define a single schema for your entire form and pass it to the form-level validators; errors will automatically propagate to the fields. ### Standard Schema Libraries @@ -489,7 +489,7 @@ function App() { } ``` -Async validations on form and field level are supported as well: +Async validators at the form- and field-level are supported as well: ```tsx