135 lines
4.2 KiB
Markdown
135 lines
4.2 KiB
Markdown
![]() |
---
|
||
|
tags:
|
||
|
- Programming_Languages
|
||
|
- javascript
|
||
|
- react
|
||
|
- react-classes
|
||
|
---
|
||
|
|
||
|
# Managing forms with class components
|
||
|
|
||
|
We are going to create a simple form that takes two integers from input fields and returns their sum. Here is the raw component:
|
||
|
|
||
|
```jsx
|
||
|
class Form extends React.Component {
|
||
|
render() {
|
||
|
return (
|
||
|
<form>
|
||
|
<input type="number" placeholder="Please enter an integer" required />
|
||
|
<input type="number" placeholder="Please enter an integer" required />
|
||
|
<button>Calculate sum</button>
|
||
|
<output></output>
|
||
|
</form>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Adding handlers
|
||
|
|
||
|
```jsx
|
||
|
class Form extends React.Component {
|
||
|
handleSubmit = (event) => {
|
||
|
event.preventDefault();
|
||
|
// Specific state change on submit
|
||
|
};
|
||
|
render() {
|
||
|
return (
|
||
|
<form onSubmit={this.handleSubmit}>
|
||
|
<input type="number" placeholder="Please enter an integer" required />
|
||
|
<input type="number" placeholder="Please enter an integer" required />
|
||
|
<button>Calculate sum</button>
|
||
|
<output></output>
|
||
|
</form>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
- The overall handling of the form is going to execute on the submission of the form. So we create an `onSubmit` event within the form body and tie this to a handling function (`handleSubmit`) on the class.
|
||
|
|
||
|
- We follow the custom of generic naming of event methods with `handle[event]` , just like we use `handleClick` with `onClick` events
|
||
|
- The `event` object is a React wrapper for the standard DOM event. We operate on this object when managing the state of forms using React.
|
||
|
- `preventDefault` is just the React method of the traditional prevent default method that we can apply to forms. It stops the page updating when the submit button is clicked.
|
||
|
|
||
|
## Capturing input values through state change
|
||
|
|
||
|
In order to retrieve the values that the user enters we need to introduce state to the form component. This is managed using the `onChange` event. Even though the overall form action should be managed through `onSubmit` we need to initialize state on the inputs we intend to use when the form is submitted. This enshrines the React principle of **lifting state up**. As the `input` elements are constituents of the overall `form` component, their state should be handled by this common parent.
|
||
|
|
||
|
### Initializing `input` state with `onChange` events
|
||
|
|
||
|
To begin with let's just look at how we would do this in the abstract with a single `input` before applying it to the two inputs in our example:
|
||
|
|
||
|
```html
|
||
|
<input
|
||
|
type="number"
|
||
|
placeholder="Please enter an integer"
|
||
|
value="this.state.integerFirst"
|
||
|
onChange="this.handleChange"
|
||
|
required
|
||
|
></input>
|
||
|
```
|
||
|
|
||
|
We tie the state parameters in the `input` element to a `handleChange` function on the parent component but we first need to add the starting state (using `this.state` on the `Form` components' constructor:
|
||
|
|
||
|
```jsx
|
||
|
class Form extends React.Component {
|
||
|
constuctor(props) {
|
||
|
super(props);
|
||
|
this.state = {
|
||
|
integerFirst: " "
|
||
|
};
|
||
|
}
|
||
|
handleChange = (event) => {
|
||
|
this.setState(
|
||
|
{
|
||
|
integerFirst: event.target.value
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Now the `Form` component is kept in the loop. Whenever the user alters the `input` field, this change will be logged as a state change within React. This will allow us to retrieve the values that the inputs have when the submit event fires.
|
||
|
|
||
|
## Handling multiple inputs
|
||
|
|
||
|
It would be inefficient to have a change handler for every input in a form with many inputs. In this scenario it is better to use destructuring to capture all the values:
|
||
|
|
||
|
```jsx
|
||
|
class Form extends React.Component {
|
||
|
constuctor(props) {
|
||
|
super(props);
|
||
|
this.state = {
|
||
|
integerFirst: "",
|
||
|
integerSecond: ""
|
||
|
};
|
||
|
}
|
||
|
|
||
|
returnSum = (x,y) => x + y;
|
||
|
|
||
|
handleSubmit = (event) => {
|
||
|
event.preventDefault()
|
||
|
this.setState({
|
||
|
outputSum: this.returnSum(
|
||
|
Number(this.state.integerFirst), Number(this.state.integerSecond)
|
||
|
)
|
||
|
});
|
||
|
|
||
|
handleChange = (event) => {
|
||
|
this.setState(
|
||
|
{
|
||
|
[event.targe.name]: value
|
||
|
}
|
||
|
)}
|
||
|
render() {
|
||
|
return(
|
||
|
<form onSubmit={this.handleSubmit}>
|
||
|
<input type="number" name="integerFirst" placeholder="Please enter an integer" onChange="this.handleChange" required />
|
||
|
<input type="number" name="integerSecond" placeholder="Please enter an integer" onChange="this.handleChange" required />
|
||
|
<button>Calculate sum</button>
|
||
|
<output></output>
|
||
|
</form>
|
||
|
)
|
||
|
}};
|
||
|
|
||
|
```
|