Reputation: 228
I'm trying to validate phone number input in the React JS component by using if/else statement. I would like to show a message("please check phone number") if the user types letters instead of numbers. So far, I was able to create a function, that checks if the input value is numbers only, but I can't figure out how to show the message alert(like in Bootstrap/reactstrap) if the user inputs letters.
My code is
import React, { useState } from "react";
import { Alert } from "reactstrap";
export default () => {
const [number, setNumber] = useState(" ");
const numberHandleChange = (e) => {
e.preventDefault();
const re = /^[0-9\b]+$/;
if (e.target.value === "" || re.test(e.target.value)) {
setNumber(e.target.value);
console.log(e.target.value);
} else {
alert("please check your phone number");
}
};
return(
<label htmlFor="phone">
<h5>Phone</h5>
<input
type="tel"
name="phone"
id="phone"
placeholder="+0 000 00 00"
onChange={numberHandleChange}
/>
</label>
)}
I tried importing Alert from Bootstrap and Reactstrap to use inside else function, it doesn't work. Alert is not showing up, and also the input field lets print letters too.
Any suggestions are greatly appreciated.
Thank you.
Upvotes: 1
Views: 6685
Reputation: 1774
@Lema, I am of the view that if you control the state of the input, it's better you assign the value of that state when you update it with the onChange event handler.
A few notes: On line 5: you declare the
number
state and always update it when the input changes on line 11, but you don't assign it anywhere. You also import the reactstrapAlert
but are not using it, instead using the browser alert(am wondering if you think they might be connected!). The browser alert, hijacks the react state updates and pauses the other browser events, and once it's dismissed, we see the invalid value assigned to the form much as the handler regex caught it!
Better approach would be giving react total control of the DOM input Comment: 5. And also put an error piece of state Comment: 2, so when the value is invalid, you don't bother updating it but just update the error Comment: 4.
The problem though is that when you were assigning the value={number}
on the input with what you set as the initial state of the number, a space character =" "
, Comment: 1 it failed at e.target.value === "" || re.test(e.target.value
, and always returns the else error. Maybe that's why you removed the value from the input in the first place. So I updated that to set initial state to no character at all and it works okay.
import React, { useState } from "react";
// import { Alert } from "reactstrap";
import "./styles.css";
export default () => {
const [number, setNumber] = useState(""); // 1. Note, no space between the quotes
const [error, setError] = useState(""); // 2. Track the error in the input
const numberHandleChange = e => {
e.preventDefault();
const re = /^[0-9\b]+$/;
if (e.target.value === "" || re.test(e.target.value)) {
setNumber(e.target.value);
setError(""); // 3. Clear the error if input is valid
console.log(e.target.value);
} else {
// alert("please check your phone number");
// 4. Set the error on invalid input
setError("❌ Only accept number characters between 0-9");
}
};
return (
<label htmlFor="phone">
<h5>Phone</h5>
<input
type="tel"
name="phone"
id="phone"
placeholder="+0 000 00 00"
value={number} // 5. Give react total control over the input.
onChange={numberHandleChange}
/>
{error && <span className="error">{error}</span>}
</label>
);
};
Upvotes: 1
Reputation: 77
The alert is shown on my screen and the logic of the code seems fine. Maybe you are somehow preventing popups? The codesandbox works as intended. What do you mean by the input field lets print letters? Generally, React uses Alert with Alert
. You can import this. You can also use if and else statements with this.
Upvotes: 0
Reputation: 1956
Your input field is not bound to the number variable you declared with setState
Add value={number}
as a prop of input.
You can't output a DOM element from your function.
Typically, you'd declare an error variable and conditionally output a React Alert
.
For example, you can declare another state hook for 'isError` and set it in your else block to true.
Then you can use a ternary in your return statement. Something like,
{isError? <Alert>Some text</Alert> : false}
Or, the shorthand:
{isError && <Alert>Some text</Alert>}
Just a thought, what will dismiss this alert? Also, you will need a React Fragment to wrap the new Alert element.
Depending on your version, the shorthand <>
and </>
will do the trick...
Upvotes: 1