When you use conditionals inside the
Take a look at the below code. I am limiting input to digits only. When I type a number, the
import { useEffect, useRef, useState } from "react";
const App = () => {
const [isValid,setIsValid] = useState(true)
const [inputValue,setInputValue] = useState("")
const prevInputValue = usePrevious(inputValue)
useEffect(() => {
if(inputValue.match(/[a-z]/i)){
setIsValid(false)
//This block executes for every alpha input
console.log("isValid set to false")
}
else {
setIsValid(true)
//This block executes for every numeric input
console.log("isValid set to true")
}
},[inputValue, isValid])
return (
<div>
<input type="text" onChange={(e) => setInputValue(e.target.value)}/><br/>
{!isValid && <>Inalid<br/></>}
<button disabled={!isValid}>Submit</button>
</div>
);
}
export default App;
I must pay attention to the variables used in the if and else conditions to fix that. If the
if(previousInputValid === true && currentInputValid === false){
setIsValid(false)
}
else
if(previousInputValid === false && currentInputValid === true){
setIsValid(true)
}
Here is the complete code example to illustrate that. I have created a custom hook to obtain the previous value. You can read more about it in Accessing the previous state in React Js
import { useEffect, useRef, useState } from "react";
const App = () => {
const [isValid,setIsValid] = useState(true)
const [inputValue,setInputValue] = useState("")
const prevInputValue = usePrevious(inputValue)
useEffect(() => {
if(!prevInputValue?.match(/[a-z]/i) && inputValue.match(/[a-z]/i)){
setIsValid(false)
console.log("isValid set to false")
}
else
if(prevInputValue?.match(/[a-z]/i) && !inputValue.match(/[a-z]/i)){
setIsValid(true)
console.log("isValid set to true")
}
},[inputValue, isValid, prevInputValue])
return (
<div>
<input type="text" onChange={(e) => setInputValue(e.target.value)}/><br/>
{!isValid && <>Inalid<br/></>}
<button disabled={!isValid}>Submit</button>
</div>
);
}
export default App;
const usePrevious = (value: string) => {
const previousValue = useRef<string>()
useEffect(() => {
previousValue.current = value
}, [value])
return previousValue.current
}