I have a MaterialUI Textfield for email which validates input when the user leaves the field. I make use of a function on onBlur for that purpose. I want to show an error message using helpertext.
The code for email field:
<TextField
margin="dense"
id="emailAddress"
name="email"
label="email"
type="email"
onChange={onChange}
onBlur={validateEmail}
value={email}
error={validEmail}
helperText={validEmail ? 'Please enter a valid Email' : ' '}
fullWidth
/>
The validEmail variable is initialized inside the functional component as follows:
let validEmail = false;
And validateEmail is defined inside the same component as:
const validateEmail = () => {
if (!email || invalidEmail(email)) {
validEmail = true;
} else {
validEmail = false;
}
};
But it doesn't work and error message doesn't get displayed. What am I potentially missing here? The condition that checks invalidEmail does get executed.
I think the right way to do so is by using internal state of the component:
class EmailComponent extends React.Component {
state = {
validEmail: false,
email: '',
};
onChange = (e) => {
...
this.setState({
email: e.target.value
});
}
validateEmail = (e) => {
const email = e.target.value;
if (!email || invalidEmail(email)) {
this.setState({
validEmail: true,
});
} else {
this.setState({
validEmail: false,
});
}
}
render () {
const { validEmail, email } = this.state;
return (
<TextField
margin="dense"
id="emailAddress"
name="email"
label="email"
type="email"
onChange={this.onChange}
onBlur={this.validateEmail}
value={email} //I think you should also set email as a state
error={validEmail}
helperText={validEmail ? 'Please enter a valid Email' : ' '}
fullWidth
/>
);
}
}
Changing the value of a variable inside a stateless component won't let you achieve what you want since the component will not render again unless one of the props or the state is changed.
Edit: Use a parent component where you handle the state
class ParentComponent extends React.Component {
state = {
validEmail: false,
email: '',
};
onChange = (e) => {
this.setState({
email: e.target.value
});
}
validateEmail = (e) => {
const email = e.target.value;
if (!email || invalidEmail(email)) {
this.setState({
validEmail: true,
});
} else {
this.setState({
validEmail: false,
});
}
}
render () {
const { validEmail, email } = this.state;
return (
<ChildComponent
email={email}
validEmail={validEmail}
onChange={this.onChange}
validateEmail={this.validateEmail}
/>
);
}
}
const ChildComponent = (props) => (
<TextField
margin="dense"
id="emailAddress"
name="email"
label="email"
type="email"
onChange={props.onChange}
onBlur={props.validateEmail}
value={props.email}
error={props.validEmail}
helperText={props.validEmail ? 'Please enter a valid Email' : ' '}
fullWidth
/>
);