У меня есть реагирующий собственный компонент ввода, который принимает регулярное выражение и выдает логическое значение, если регулярное выражение совпадает.
Я хотел сделать то же самое, но вернуть строковое значение в React Js, но проблема в том, что я не совсем понимаю, как работает собственный компонент ввода реакции.
Пользовательский компонент ввода
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>
);
}
}
Применение
<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
/>
Теперь я хочу создать компонент в ReactJs, который имеет вход и другие элементы, ввод которых будет принимать регулярное выражение, и он будет возвращать значение своего ввода родителю. Он будет использоваться в форме, которая будет иметь много входных данных, и все входные данные должны иметь сообщения об ошибках и проверки.
Я понял логику, если кто-то хочет сделать такой ввод, он может использовать этот код
Я использовал react-bootstrap для стилизации
Пользовательский ввод
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 handleChangeEvent = (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) => handleChangeEvent(e.target.value)}
/>
{showError && error ? (
<small className = "text-danger">{error}</small>
) : null}
</div>
);
}
И используйте его в родительском компоненте, подобном этому
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)}
/>
Кто-нибудь, пожалуйста, подтвердите, хороший ли это подход
Вы можете создать пользовательский компонент с контролируемым состоянием. Вам необходимо установить локальное состояние в пользовательском компоненте. При изменении значения вы можете проанализировать и проверить. после этого установите его в локальное состояние. Вы можете использовать ошибку либо локально, либо делегировать родительскому. Здесь ниже пример, я делегировал родительскому элементу проверку.
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>
);
};