Objective
Create a form with an input field that can't be submitted empty.
Description
Consider the following HTML form containing a text input and a button to submit the form:
If the form is submitted with the input field empty, the form doesn't actually get submitted, i.e. its default action is prevented.
In this case (that is, when the input field is empty and the form is submitted), an error message, colored red, is shown right next to the input field as shown below:
However, when the input is not empty and the form is submitted in this state, an alert message is shown as follows:
Keep in mind that in neither case is the form actually submitted (that is, no HTTP request is made to send the form). The <form>
element is purely meant to represent a form in the document's content; it doesn't actually behave like a traditional form in its submission.
In this exercise, you have to create a program containing the form described above.
The form should be directly a part of an App
component in your program.
Moreover, keep in mind that you should NOT use state to obtain the value of the <input>
element.
While it is obviously possible to use state, you should try solving the exercise without it for the <input>
element and test your knowledge of using other ways to interact with an <input>
element in a form in React.
New file
Inside the directory you created for this course on React, create a new folder called Exercise-11-Can't-Be-Empty and put the .js solution files for this exercise within it.
Solution
Let's start by setting up the general structure of the App
component, containing the form:
function App() {
return (
<form>
<input type="text" />
<br/>
<button>Submit</button>
</form>
);
}
Now, let's set up the onSubmit
event handler prop on <form>
and prevent the default action in there to begin with:
function App() {
function handleSubmit(e) {
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<input type="text" />
<br/>
<button>Submit</button>
</form>
);
}
As stated in the description above, there is no need to use state. Likewise, in order to retrieve the value of the input, we can use a ref on the <input>
element, named inputRef
.
This is done as follows:
import { useRef } from 'react';
function App() {
const inputRef = useRef();
function handleSubmit(e) {
e.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
<br/>
<button>Submit</button>
</form>
);
}
If the retrieved value is an empty string, i.e. there is nothing entered into the input, we should display an error message right next to the <input>
element by rendering a <span>
containing the message.
This mandates us to use state to trigger a re-render of the App
component with a state value called error
set to a string describing an error message — this state value is initialized to null
because initially no error ought to be shown.
Here's the complete code obtained thus far:
import { useState, useRef } from 'react';
function App() {
const inputRef = useRef();
const [error, setError] = useState(null);
function handleSubmit(e) {
e.preventDefault();
if (inputRef.current.value === '') {
setError("Can't be empty!");
}
}
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
{error && <span style={{ color: 'red' }}>{error}</span>}
<br/>
<button>Submit</button>
</form>
);
}
On the other side of the mirror, if the input value is not an empty string, we should alert the message 'Submitted'. This can either be done by using an else
statement, or by returning control in the if
statement and then having a normal statement following the if
conditional.
We'll go with the latter, as shown below:
function App() {
const inputRef = useRef();
const [error, setError] = useState(null);
function handleSubmit(e) {
e.preventDefault();
if (inputRef.current.value === '') {
setError("Can't be empty!");
return;
}
setError(null);
alert('Submitted');
}
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} />
{error && <span style={{ color: 'red' }}>{error}</span>}
<br/>
<button>Submit</button>
</form>
);
}
Let's now test this implementation of App
:
It works absolutely perfectly!
And this completes this exercise.