I have a form where one of the fields needs a very specific validation. I want to be able to reuse this fields in other forms without the form having to re-implement the validation method again and again.
I thought extracting the input field to its own component, DomainInput
would work:
<div id="domain-input-area" class={this.state.showDomain ? '' : 'base-remove'}>
<DomainInput/>
</div>
DomainInput
then contains all the validation logic for itself
import { Component } from 'react';
//import '../../../login-box/login-box.styles.css'
import '../domain-input/domain-input.styles.css';
class DomainInput extends Component{
constructor(){
super();
this.state = {
domain:'',
valid:false,
error:''
};
}
handleDomainInput = (e) => {
let domain = e.target.value;
let error = '';
let valid = true;
if(domain.indexOf('my.salesforce.com') === -1){
error = `${this.state.domain} is not a valid salesforce domain`;
valid = false;
this.setState({error:error,valid:valid});
}
if(domain.indexOf('https://') != 0){
error = `Please use https://`;
valid = false;
this.setState({error:error,valid:valid});;
}
if(valid){
domain = domain.trim();
let lastCharacter = domain.substr(domain.length-1);
//remove last slash
if(lastCharacter === '/'){
domain = domain.substr(0,domain.length-1);
}
this.setState({domain:domain,valid:true});
}
}
render(){
return (
<input type="text" placeholder="https://your-domain.my.salesforce.com" class={this.state.valid ? 'base-input valid' : 'base-input invalid'} id="domain-input" onChange={this.handleDomainInput}/>
)
}
}
export default DomainInput
My idea was that when DomainInput
knew that its state was valid, it would fire an event to the parent component (the form) to let it know that it has been validated.
But I realised this is not the react way due to one-way data flow, and instead the onChange
handler should be implemented in the parent, which as I said, I don't want to do because I want to be able to drop DomainInput
in any form, and have it validate itself.
Other frameworks like LWC allow child components to send custom events to the parent. In my case, it would send a validated
event and this would in turn set the parent's state to validDomain:true
How do I do this the react way?
To give you an idea, how you can do with parent (manages state) and child (Custom Input Field), Here's sample code:
TextField.jsx
export const TextField = ({error, ...rest}) => {
return (
<div className="mb-6">
<label htmlFor={rest.name} className="">
{rest.label}
</label>
<input
type="text"
{...rest}
className={ '' + (!!error ? ' border-red' : '')}
/>
{error && <div className="...">{error}</div>}
</div>
)
}
ParentComponent.jsx
this.state = { email: '', error: '' }
<TextField
label="Email Address"
name="email"
value={this.state.email}
placeholder="doge@example.com"
onChange={handleChange}
onBlur={handleBlur}
error={state.error}
/>
Now validate your input and set the state accordingly in the parent component using custom handleChange and handleBlur functions as follow:
handleChange = (event) => {
let { name, value } = event.target
// set state here and also validate
}
handleBlur = (event) => {
let { name, value } = event.target
// set state here and also validate
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.