Reputation: 376
I have a react native input component that takes a regex and emit a boolean if the regex matches.
I wanted to do the similar thing but return a string value in React Js but the problem is I don't totally understand how the react native input component is working.
Custom Input component
class CustomInput extends Component {
handleValidation(value) {
const {pattern} = this.props;
if (!pattern) {
return true;
}
// string pattern, one validation rule
if (typeof pattern === 'string') {
const condition = new RegExp(pattern, 'g');
return condition.test(value);
}
// array patterns, multiple validation rules
if (typeof pattern === 'object') {
const conditions = pattern.map(rule => new RegExp(rule, 'g'));
return conditions.map(condition => condition.test(value));
}
}
onChange(value) {
const {onChangeText, onValidation} = this.props;
const isValid = this.handleValidation(value);
onValidation && onValidation(isValid);
onChangeText && onChangeText(value);
}
render() {
const {pattern, onChangeText, children, style, ...props} = this.props;
return (
<Input
style={style}
onChangeText={value => this.onChange(value)}
{...props}
autoCapitalize="none">
{children}
</Input>
);
}
}
Usage
<CustomInput
value={pass} //state variable
onChangeText={onChangePass} //state variable setter
pattern={[regexes.password]}
onValidation={isValid => performValidation(isValid)}
//performValidatio method enables and disables a button according to isValid
/>
Now I want to make a component in ReactJs that has an Input and other elements the input will take a regex and and it will return the value of its input to the parent. It will be used in a form that will have many inputs and all inputs need to have and error msg and validations.
Upvotes: 1
Views: 1465
Reputation: 8135
You can create custom component with controlled state. You need to set local state within the custom component. On change of value, you can parse and validate. after that set it to local state. You can leverage error either local of delegate to parent. Here below sample, i have delegated to parent on validation.
const Input = ({
onChangeText,
pattern,
onValidation,
defaultValue,
error,
...rest
}) => {
const [value, setValue] = useValue(defaultValue);
const onChange = ({ target: { value } }) => {
if (pattern) onValidation(pattern.test(value));
setValue(value);
onChangeText(value);
};
return (
<div className="wrapper">
<input value={value} onChange={onChange} {...rest} />
{error && <span>{error}</span>}
</div>
);
};
Upvotes: 1
Reputation: 376
I have understood the logic if anyone wants to make an input like this they can use this code
I have used react-bootstrap for styling
The Custom Input
import React, { useState } from "react";
export default function CustomInput(props) {
const { error, inputProps, regex, className, onInput } = props;
const [showError, setShowError] = useState(false);
const [text, setText] = useState("");
const handleChange = (val) => {
setText(val);
if (regex.test(val)) {
setShowError(false);
} else {
setShowError(true);
}
onInput && onInput(val);
};
return (
<div className={className}>
<input
value={text}
className={showError ? "form-control border-danger" : "form-control"}
{...inputProps}
onChange={(e) => handleChange(e.target.value)}
/>
{showError && error ? (
<small className="text-danger">{error}</small>
) : null}
</div>
);
}
And use it in a parent component like this
const [temp, setTemp] = useState("");
<CustomInput
className="form-group col-md-3"
inputProps={{ placeholder: "test", maxLength: "50" }}
error="Required"
regex={regexes.url}
onInput={(val) => setTemp(val)}
/>
Somebody please confirm if this is a good approach
Upvotes: 0