Forms & inputs are a core fundamental of building any kind of web app and they can come with a decent amount of complexity because they can become really complicated and sprawling state machines. The rest of the guide has some recommendations and code snippets to help you manage forms in a way that is simple, scalable and maintainable.
## Inputs
As a general rule of thumb, inputs should be controlled components. "Controlled" means that the value of the input is controlled by the state of the component and not the DOM. In practice means that there is a `value`, an `onChange` and somewhere where the value is stored in state.
This could be primitive values like a string or more complex objects, the important thing is that the input represents a clear boundary between the component where the value is gathered from the user and the component where the value is used.
```tsx
const [value, setValue] = useState<string>('');
return <TextInput value={value} onChange={updated => setValue(updated)} />;
```
### What makes a good input
A good input should be able to be used in any context where the value it represents needs to be gathered. That doesn't mean that every input should be used in every context. You might find yourself with an input that will never be used in another context and that's fine. The important thing that nothing about the input is tied to the context in which it is used and it's the best representation of the value it represents.
Similarly, you might find yourself in a situation where you need to use an input in a context where it doesn't quite fit.
If you find yourself adding flags or conditional logic to an input to make it fit a context and especially if that logic changes the value, you should consider creating a new input that is a better representation of the value you are trying to gather. If you're copy and pasting a ton of code to do that, try pulling out container components, validation messages or styling that can be shared between the inputs.
## State
Forms are a composition of inputs that are part of the same data gathering exercise and will be submitted together. The line gets a bit more blurry here because of complex nature of some of the apps we want to build. For example, what if a form is a wizard that has multiple steps? What if inputs have dependencies on each other or we need to use derived values?
[react-hook-form](https://react-hook-form.com) is a great library for managing form state. Like with all good libraries, whenever I go to roll my own form state management I always end up with something that looks a lot like `react-hook-form` but worse so I now just use it from the start. It's a good middle ground between aligning with a standard html form style approach, i.e. `<form>`, `onSubmit`, `e.preventDefault()`, etc and a more flexible but complex state management approach.
### Submitting the form
### Derivatives
### Optimistic UI
## Validation
## Labels
## Fields