I have a question regarding validation of inputs. I'm using Fabric UI for the textfields, which have onGetErrorMessage, which I'm using to validate input. The textfield is a controlled element. It is all working well, except one moment, when I do a reset / clear of the fields, it triggers the validation and then I get error messages, saying cannot be empty, which is fine due to the validation, but not fine if we are talking about reset.
I'll post here parts of the code which I use.
const els: React.ReactElement[] = [];
els.push(<ChoiceGroup label = "Choice" selectedKey = {student.Choice} options = {choices} onChange = {(e: any, selectedItem: any) => ...} />);
els.push(<TextField label='Name' required value = {student.Name} onChange = {(e: any, value: any) => ....} validateOnLoad = {false}
onGetErrorMessage = {(value: string) => validate('Name', value, els)} />);
els.push(<TextField key='Age' label="Age" required value = {student.Age} onChange = {(e: any, value: any) => ..} validateOnLoad = {false}
onGetErrorMessage = {(value: string) => validate('Age', value, els)} />);
We have 3 elements, which are shown, now on choice change, I need to clear the textfields, which I do as follows:
useEffect(() => {
// I modify the state here, and set Age and Name of the student object to ''
// which triggers then onGetErrorMessage
}, [student.Choice]);
What is the best way to reset values of the textfields, without triggering validate, but this still has to work when user manually clears textfield (making it empty)
Any idea? I would appreciate .... been stuck with it for some time...
Since you explained the behavior of validateOnLoad
you can supply keys to your textfields:
<TextField
label="Name"
key={uniqueKey}
required
value={student.Name}
onChange={(e: any, value: any) => {
/* ... */
}}
validateOnLoad={false}
onGetErrorMessage={(value: string) => validate("Name", value, els)}
/>;
Now, when you clear Age
and Name
inside useEffect
, you can also regenerate keys of each text field. The key should be a unique value like UUID. This will make react unmount the previous instance of each Textfield
and mount it again - which will give you same behavior you had when you initially created each text field.
The keys should be generated initially once, and also make sure you regenerate those keys in useEffect
when you want to clear those text fields, and not inside render on each rerender (see example below).
Example:
import React from 'react';
import './style.css';
// Using this function for this example, not sure if this is the safest way to generate uuidv4
function uuidv4() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
(
c ^
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
).toString(16)
);
}
export default function App() {
let [a, setA] = React.useState(uuidv4());
let [b, setB] = React.useState(uuidv4());
let [test, setTest] = React.useState(0);
React.useEffect(() => {
setA(uuidv4());
setB(uuidv4());
}, [test]);
return (
<div>
<input key={a}></input>
<input key={b}></input>
<button
onClick={() => {
setTest(test + 1);
}}
>
click
</button>
</div>
);
}