Redux Form异步验证无限递归

时间:2017-09-27 13:38:50

标签: reactjs redux-form

我在我的应用程序中使用redux-form@7.0.4。在某些领域我需要动态定义验证功能。 请注意,我需要 id 切片才能在值中查找正确的字段

<Field
    component={SemanticFormField}
    as={Input}
    placeholder="From"
    name={"participation-card-" + id + "-slice-" + slice + "-min"}
    validate={[number]}
    />
<Field
    component={SemanticFormField}
    as={Input}
    placeholder="to"
    name={"participation-card-" + id + "-slice-" + slice + "-max"}
    validate={[number, validateMaxSlice(slice, id)]}
    />

当我像这样定义validateMaxSlice时

const validateMaxSlice = (slice, id) => (value, values) => {
    const min = values["participation-card-" + id + "-slice-" + slice + "-min"];
    return min >= value ? "Invalid slice" : undefined;
};

或者像这样内联

validate={[number, (value, values) => {
const min = values["participation-card-" + id + "-slice-" + slice + "-min"];
    return min >= value ? "Invalid slice" : undefined;}]

应用程序在呈现组件时会进入无限循环。

问题是为什么以及如何解决它?

修改

感谢您的帮助!这是我实现它的方式

容器部分:

createSlice() {
    const id = uuidv4();
    return {
        id,
        validators: (value, values) => {
            const min = values["participation-card-" + this.props.id + "-slice-" + id + "-min"];
            return valSup(value, "Tranche incorrecte")(min);
        },
    };
}

addParticipationSlice() {
    let participationSlices = this.state.participationSlices;

    participationSlices.push(this.createSlice());

    this.setState({
        participationSlices,
    });
}

场景部分:

<Field
    component={SemanticFormField}
    as={Input}
    name={"participation-card-" + id + "-slice-" + slice.id + "-max"}
    size="mini"
    width={7}
    validate={[number, slice.validators]}
/>

1 个答案:

答案 0 :(得分:2)

在动态创建验证器时,每次重绘时都会创建一个新的验证器实例。

在第一次重绘时,React尝试验证该值,然后重绘以更新视图。反过来,这会创建一个新的验证函数并更改相关的道具值。

当您将道具更改为组件时,react将触发重新渲染Field。因此导致它再次重新验证,再次导致重新渲染。

纠正它的一种方法是生成每个回调的一个且只有一个版本,在适当的时候重用函数实例。

例如,您可以存储this.validators关联数组,然后将函数生成器更改为以下内容:

validateMaxSlice(slice, id) => {
     if (!this.validators[`${slice}-${id}`]) {
          this.validators[`${slice}-${id}`] = (value, values) => { ...Actual validation code... }
     }
     return this.validators[`${slice}-${id}`]
}

这样,验证器即时创建,但可以在需要的地方重复使用。