У меня есть React Component (изначально написанный кем-то другим), который отображает форму для человека (redux-form) Недавно я изменил компонент на FieldArray (компонент redux-form).
У меня есть проверка для поля электронной почты, которое влияет на className для поля электронной почты (красного цвета, если электронная почта неправильно отформатирована, черный цвет в противном случае). Он работал хорошо, когда он не был FieldArray, но теперь он проверяет все поля электронной почты одновременно из-за
// (in constructor)
this.email = React.createRef();
// (in Field)
ref={props.parent.email}
, т.е. props.parent.email является глобальным / stati c ref.
Пример: есть два человека. Один из них имеет неправильно отформатированный адрес электронной почты, но оба сообщения отображаются красным цветом.
Насколько я понимаю, мне нужен динамический c ref, но это не сработало так, как я пытался ,
ref={`${person}.email.ref`}
Ошибка
"Компоненты функций не могут иметь ссылок. Вы имели в виду использовать React.forwardRef ()?"
Я не сделал Не могу найти ничего полезного в forwardRef в отношении FieldArray, кроме того факта, что он является действительным реквизитом.
Моя цель: когда несколько человек созданы пользователем и / или загружены из магазина Redux, смогут показать каждое правильно отформатированное письмо в черном цвете, и каждое неправильно отформатированное письмо в красном.
Любая помощь очень ценится!
import React from "react";
import { Field, reduxForm, FieldArray } from "redux-form";
import { connect } from "react-redux";
import classNames from 'classnames'
import { MAIL_PATTERN } from "../some_file";
import MoreGeneralComponent from "../some_other_file";
const renderField = ({ input, label, type, options, className, meta: { touched, error }, style, disabled, hidden }) => (
<div style={style}>
<label>{label}</label>
<div>
<input {...input} disabled={disabled ? true : false} hidden={hidden ? true : false} type={type} placeholder={label} className={className} />
</div>
</div>
);
const renderPerson = ({ fields, meta: { error, submitFailed }, ...props }) => {
setTimeout(props.validate(fields));
return (
<ul className="personlist">
{fields.map((person, index) => (
<li key={index} className="person">
<h4>Person #{index + 1}</h4>
<Field
component={renderField}
type="text"
ref={props.parent.email}
className={classNames({invalid: !props.parent.state.validEmail})}
validate={props.parent.validateEmail}
name={`${person}.email`}
label="Email"
key={`${person}.email`}
></Field>
<button type="button" onClick={() => fields.remove(index)}>
Remove
</button>
</li>
))}
{(!(fields.length >= props.max)) && (
<li className="addperson">
<button
type="button"
onClick={() => fields.push({})}
disabled={fields.length >= props.max}
>
Add Person
</button>
{submitFailed && error && <span>{error}</span>}
</li>)}
</ul>
);
};
class Person extends MoreGeneralComponent {
constructor(props) {
super(props);
if (this.state.ready) {
this.max = 4;
this.data = ["email"];
this.email = React.createRef();
}
}
validate = fields => {
if (!fields || !fields.getAll()) {
return;
}
let valid = true;
fields.getAll().forEach(field => {
for (let d of this.data) {
if (!field[d] || field[d].length < 2) {
valid = false;
return;
} else if (d === "email") {
valid = field[d] && MAIL_PATTERN.test(field[d]) ? valid : undefined;
}
}
});
if (valid !== this.state.valid) {
this.setState({
valid: valid
});
}
};
validateEmail = (value) => {
const valid = value && MAIL_PATTERN.test(value) ? value : undefined;
this.setState({validEmail: !!valid});
return valid
}
renderQuestion() {
return (
<div className={style.question}>
<fieldset>
<FieldArray
name="persons"
component={renderPerson}
props={{ max: this.max, validate: this.validate, parent: this }}
rerenderOnEveryChange={true}
/>
</fieldset>
</div>
);
}
}
const mapStateToProps = s => {
const persons = s.persons
var initialValuesPersons = []
persons.map(item => initialValuesPersons.push({
"email": item.email || ""
}))
var initialValues = { "persons": initialValuesPersons}
return {
initialValues,
formdata: s.form
}
}
export default connect(mapStateToProps, null)(reduxForm(
{
form: 'person',
destroyOnUnmount: false,
enableReinitialize: true,
keepDirtyOnReinitialize: true
})(Person))