Redux-Form:更改 FieldArray 提交父表单

Redux-Form: Change in FieldArray submits parent form

我遇到了 redux-form 的问题。我有一个正在填充 initialValues 的表单。在顶层表单中,我有一个 FieldArray 呈现输入字段列表。每个输入字段都有用于将其删除(通过 fields.remove(index))或在其后立即插入另一个输入(通过 fields.insert(index+1))的按钮。我的问题是:当我调用 fields.insert() 时,新字段被正确插入和注册,但父表单被提交,这是不应该的。当数据数组至少有一项时,fields.push() 也会发生同样的情况。但它不在例如fields.remove()fields.removeAll()。我不知道 why/where 提交发生了。我花了几个小时来挖掘源代码并试用官方的 FieldArray 示例,它确实有效。我在网上找不到问题所以我想我在某处有错误,因为这与正在使用的 redux-form 版本无关(已尝试 >=6)。

感谢您的帮助,这是代码。

家长表

import React from 'react';
import { Field, FieldArray, reduxForm } from 'redux-form';

import Row from 'muicss/lib/react/row';
import Col from 'muicss/lib/react/col';
import Button from 'muicss/lib/react/button';
import MaterialInput from '../material/material-input';
import MaterialSelect from '../material/material-select';
import MaterialFieldArray from '../material/material-fieldarray';

import Cover from './cover';
import CheckboxGroup from './checkbox-group';

const MovieDetailsEditForm = props => {

    const { handleSubmit, initialValues: { cover: { large: cover }, directors = [], actors = [] } } = props;

    const getFSKOptions = () => {
        return [
            {value: 0, label: 0},
            {value: 6, label: 6},
            {value: 12, label: 12},
            {value: 16, label: 16},
            {value: 18, label: 18}
        ];
    };

    const getFormats = () => {
        return [{value: 'DVD', label: 'DVD'}, {value: 'Blu-ray', label: 'Blu-Ray'}];
    }

    const getImages = () => props.initialValues.images.map( (image) => ({ value: image.large, checked: false }) );

    return (
        <Row>
            <form className="mui-form" onSubmit={handleSubmit(props.handleFormSubmit)}>
                <Col xs="12">
                    <Button type="submit" color="primary">Speichern</Button>
                </Col>
                <Col xs="12">
                    <Row>
                        <Col xs="12" md="6">
                            <Row>
                                <Col xs="12">
                                    <Field name="title" id="title" component={MaterialInput} label="Filmtitel" type="text" />
                                </Col>
                                <Col xs="6">
                                    <Field name="duration" id="duration" component={MaterialInput} label={props.initialValues.unit} type="text" />
                                </Col>
                                <Col xs="6">
                                    <Field
                                        name="format"
                                        id="format"
                                        options={getFormats()}
                                        component={MaterialSelect}
                                        label="Format"
                                        parse={(value, name) => value ? value : null}
                                    />
                                </Col>
                                <Col xs="12">
                                    <Field
                                        name="fsk"
                                        id="fsk"
                                        options={getFSKOptions()}
                                        component={MaterialSelect}
                                        label="FSK Einstufung"
                                        labelText="Freigegeben ab <<PLACEHOLDER>> Jahren"
                                        parse={(value, name) => value ? value : null}
                                    />
                                </Col>
                                { directors &&
                                    <Col xs="12">
                                        <h3>Regisseur{directors.length > 1 ? 'e' : ''}</h3>
                                        <FieldArray component={MaterialFieldArray} name="directors" />
                                    </Col>
                                }
                                { actors &&
                                    <Col xs="12">
                                        <h3>Cast</h3>
                                        <FieldArray component={MaterialFieldArray} name="actors" />
                                    </Col>
                                }
                            </Row>
                        </Col>
                        <Col xs="12" md="6" className="cover">
                            <Field {...props} name="cover" id="cover" component={Cover} />
                        </Col>
                    </Row>
                </Col>
                <Col xs="12">
                    <Field {...props} name="images" component={CheckboxGroup} valueProperty="large" />
                </Col>
            </form>
        </Row>
    );

}

export default reduxForm({
    form: 'MovieDetails',
    enableReinitialize: true
})(MovieDetailsEditForm);

material-fieldarray.js

import React from 'react';
import { Field } from 'redux-form';

import Row from 'muicss/lib/react/row';
import Col from 'muicss/lib/react/col';
import Button from 'muicss/lib/react/button';

import MaterialInput from '../material/material-input';

export default props => {
    const { fields } = props;

    const addEntry = index => fields.insert(index + 1, '');
    const removeEntry = index => fields.remove(index);

    const renderEntries = () => {
        return fields.map((field, index) => {
            return (<li key={index}>
                <Col xs="7" sm="8" md="7" lg="8">
                    <Field component={MaterialInput} name={`${field}`} id={`${field}`} />
                </Col>
                <Col xs="5" sm="4" md="5" lg="4" className="buttons">
                    <Button variant="fab" size="small" color="primary" onClick={() => addEntry(index)}>+</Button>
                    <Button variant="fab" size="small" color="danger" onClick={() => removeEntry(index)}>-</Button>
                </Col>
            </li>);
        })
    }

    return (
        fields.length &&
        <ul className="inputfield-list">
            { renderEntries() }
        </ul>
        || <Button onClick={() => fields.push('')}>Add</Button>
    )
}

好的,这个问题非常微妙,与 React 或 Redux-Form 无关。我忘了将 type="button" 放在 add/remove 项到 FieldArray 的按钮上。

<Button variant="fab" size="small" color="primary" onClick={() => addEntry(index)}>+</Button>

这就是 HTML 表单的工作方式。