Form Submission in React.js
The default HTML form submission behavior still works in React.js, but it’s better to supply your own custom controls on how data is processed by a component.
Oct 20, 2020 • 7 Minute Read
Introduction
HTML form submission works differently when implementing it within a React.js component. Normally, the browser would render the HTML and, depending on the action, automatically submit the data of the form based on each element's name attribute. Although this default behavior still works in React.js, it is highly advised to programmatically submit a form by supplying your own custom controls on how data is processed by a component.
Normal HTML Form Submission
A React.js component can render HTML back to the browser where all rules still apply. To illustrate this, create the following component:
import React from 'react';
export default class FormSubmission extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<form action="https://www.youtube.com/results" method="GET">
<input type="text" name="search_query" />
<button type="submit">
Submit
</button>
</form>
</div>
);
}
}
Running this code as-is will make a submission to Youtube's https://www.youtube.com/results endpoint that expects a search_query value parameter, which is already defined as the name of the input element:
<input type="text" name="search_query" />
All HTML rules still apply, and the user will be able to search for Youtube's videos. React.js simply renders HTML.
Programmatic Form Submission
The React.js way, however, allows you to be in full control of what data is being submitted. This also means that your code will not be reliant on HTML attributes but on whatever was programmed within your component's logic. To illustrate this, modify the component to look like the following:
import React from 'react';
export default class FormSubmission extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<input type="text" />
<button>
Submit
</button>
</div>
);
}
}
There are key differences that you can observe here.
- The name attribute for the input element was dropped
- The entire form is no longer enclosed in a form tag
The key idea here is to create event handlers that deal with changes or react to changes every time a user interacts with the form elements. Specifically, these would be changing text in the input element and clicking the submit button.
Event Handling for Input
To create an event handler for the input element, first declare a state value called searchQuery to be maintained by the component. State values are initially set in the constructor:
constructor(props) {
super(props);
this.state = {
searchQuery: ""
}
}
Next, create a method called handleInputChanged:
handleInputChanged(event) {
this.setState({
searchQuery: event.target.value
});
}
Attach the event handler function to the onChange attribute of the input element:
<input type="text" value={this.state.searchQuery} onChange={this.handleInputChanged.bind(this)}/>
The value of the input is always bound to this.state.searchQuery. Every time the value in the state is updated, it will automatically reflect as the value of the input.
The bind(this) function is added in order to pass this and retain its value as the instance of the component within the handleInputChanged function. This will allow you to call setState which updates the state value of searchQuery to event.target.value, which is the current value of the input element when the call was made. This approach also applies to other input elements of HTML and not only for text inputs.
Event Handling for Button
HTML buttons would normally have the onClick attribute set to them in order to supply logic whenever the button is clicked. Similar to input, first declare a function for button clicks:
handleButtonClicked() {
var searchQuery = this.state.searchQuery;
window.location.href = "https://youtube.com/results?search_query" + searchQuery;
}
Since you'll be submitting the data to Youtube's endpoint, the logic of the function first takes the current value of searchQuery from the component's state. Any Javascript logic can be applied for form submission in this part, but for simplicity the code simply redirects to Youtube's endpoint with the search_query parameter as part of the URL. This simulates a GET request similar to the basic example earlier, only now you have more control of what values are being passed and how those values are extracted.
Finally, attach the event handler to the button's onClick attribute:
<button onClick={this.handleButtonClicked.bind(this)}>
Submit
</button>
Overall Code
The final code should look like the following:
import React from 'react';
export default class FormSubmission extends React.Component {
constructor(props) {
super(props);
this.state = {
searchQuery: ""
}
}
handleInputChanged(event) {
this.setState({
searchQuery: event.target.value
});
}
handleButtonClicked() {
var searchQuery = this.state.searchQuery;
window.location.href = "https://youtube.com/results?search_query" + searchQuery;
}
render() {
return (
<div>
<input type="text" value={this.state.searchQuery} onChange={this.handleInputChanged.bind(this)}/>
<button onClick={this.handleButtonClicked.bind(this)}>
Submit
</button>
</div>
);
}
}
Conclusion
Form submission in React.js is quite different from usual form submissions in HTML. React.js gives you full control of the values you are passing to the next actionable item, allowing you to format more complex data structures. All values are maintained by the state object of a component and are propagated throughout the elements that are rendered, such as those of an input. Event handlers are also needed in order to tell the app how to react to certain changes, such as modifying an input or clicking a button.
Moving forward, you can try to apply the concept of programmatically defining how to handle each input element of your component. Given another type of input element aside from text (i.e. select, checkbox, radio and textarea), create another state variable for it and program a corresponding event handler function bound to that input element. The logic of the function should be able to reference the input element, get its current value, and update its corresponding state variable accordingly.
For any questions/concerns, or if you simply want to chat about programming in general, hit me up @happyalampay!
Learn More
Explore these React courses from Pluralsight to continue learning: