I am trying to create a validation that automatically removes bad characters as they are typed in. The state is changing correctly and the removal is happening correctly. The problem I am having is updating the actual value of the input. I basically want to give the user a warning and then automatically remove the offending character.
I have this, which works:
const [domain, setDomain] = useState("http://example.com/");
const [url, setUrl] = useState("");
function handleSetUrl(e){
const regExp = /^[A-Za-z0-9-_]+$/;
if(e.match(regExp)){
setUrl(e)
}else{
console.log("Your URL can only contain numbers, letters, dashes and underscores.");
const modUrl = e.replace(/[^A-Za-z0-9-_]/g, '');
setUrl(modUrl)
}
}
And my input:
<p>{domain}{url}</p>
<Input
label="Page URL"
inputProps={{type: "text"}}
defaultValue={url}
onChange={(e) => handleSetUrl(e.target.value)}
/>
So when the user types in offending characters (for example /
or a space) it removes the offending character and sets my state correctly –> setUrl(modUrl)
and the constant url
reflects that. The issue I am having is trying to update the <Input
with the updated value. If I use defaultValue
it doesn’t update when I remove the offending character using:
const modUrl = e.replace(/[^A-Za-z0-9-_]/g, '');
setUrl(modUrl)
And if I just use value={url}
I am unable to edit the input at all. How do I get my input to reflect the change to setUrl
in real time?
2
Answers
What I did was set
value={url}
and set a hook withuseEffect
to listen for a state change. Effectively it "acts" likedefaultValue
While updating the input in real time:And just added to following to my codeset:
To update the input value in real time based on the modified URL, you can use the controlled component approach. Instead of using defaultValue, you can set the value prop of the component to the url state variable, and handle the input changes by updating the url state with the modified URL.