首页 > 解决方案 > 在所有主题名称字段上显示错误

问题描述

我有一个表单,用户可以在其中发布主题。在发布的主题下方显示。当主题名称或类型字段之一存在验证错误时,所有名称或类型字段都会显示为必需的名称或主题。为什么呢?onChange 事件中的验证行为不正常。

这是代码

这如果用于验证

export const validate = values => {
  const errors = {}
  const requiredFields = {
    topic_name: 'Topic Name',
    topic_type: 'Topic Type',
  }
  for (const key in requiredFields) {
    if(requiredFields.hasOwnProperty(key)) {
      if(!values[key]) {
        errors[key] = `${requiredFields[key]} is required`
      }
    }
  }
  return errors
}

话题

class Topic extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            customTopic: [],
            visible: false,
            id: '',
            topic_name: this.props.match.params.topic || '',
            topic_type: ''
        };

        this.handleChange = this.handleChange.bind(this);
    }

    componentDidMount() {
        this.props.fetchCustomTopic();
    }

    handleChange = e => {
        this.setState({ [e.target.name]: e.target.value });
    };

    simplePlainTable = topics => (
        <DataTable plain>
            <TableHeader>
                <TableRow>
                    <TableColumn>Topic Name</TableColumn>
                    <TableColumn>Topic Type</TableColumn>
                    <TableColumn>Action</TableColumn>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow>
                    <TableColumn>
                        <Field
                            placeholder="Topic Name"
                            name="topic_name"
                            id="topic_name"
                            value={this.state.topic_name}
                            onChange={this.handleChange}
                            className="input-field"
                            type="text"
                            fullWidth
                            component={TopicNameField}
                            required
                        />
                    </TableColumn>
                    <TableColumn>
                        <Field
                            placeholder="Topic Type"
                            name="topic_type"
                            id="topic_type"
                            value={this.state.topic_type}
                            onChange={this.handleChange}
                            required
                            className="input-field"
                            type="text"
                            fullWidth
                            component={TopicTypeField}
                        />
                    </TableColumn>
                    <TableColumn>
                        <Button
                            icon
                            tooltipLabel="Add"
                            onClick={e => this.addCustomTopic(e)}>
                            add
                        </Button>
                    </TableColumn>
                </TableRow>
                {topics &&
                    topics.customTopic.map((obj, i) => (
                        <TableRow key={i} id={obj.id}>
                            <TableColumn>
                                <Field
                                    placeholder="Topic Name"
                                    name="topic_name"
                                    id="topic_name"
                                    defaultValue={obj.topic_name}
                                    onBlur={e =>
                                        this.updateCustomTopic(
                                            { topic_name: e.target.value },
                                            obj.id
                                        )
                                    }
                                    required
                                    className="input-field"
                                    type="text"
                                    fullWidth
                                    component={TopicNameField}
                                />
                            </TableColumn>
                            <TableColumn>
                                <Field
                                    placeholder="Topic Type"
                                    name="topic_type"
                                    id="topic_type"
                                    defaultValue={obj.topic_type}
                                    onBlur={e =>
                                        this.updateCustomTopic(
                                            { topic_type: e.target.value },
                                            obj.id
                                        )
                                    }
                                    required
                                    className="input-field"
                                    type="text"
                                    fullWidth
                                    component={TopicTypeField}
                                />
                            </TableColumn>
                            <TableColumn>
                                <Button
                                    icon
                                    tooltipLabel="Delete"
                                    onClick={() => this.show(obj.id)}>
                                    delete
                                </Button>
                            </TableColumn>
                        </TableRow>
                    ))}
            </TableBody>
        </DataTable>
    );

    render() {
        const { topics } = this.props;
        return (
            <div className="container">
                    {this.simplePlainTable(topics)}
                    {this.dialogContainer()}
            </div>
        );
    }
}

export default reduxForm({
    form: 'wizard',
    validate
})(connect(mapStateToProps, mapDispatchToProps)(Topic));

我正在使用 redux 形式。

这就是发生的事情

在此处输入图像描述

标签: javascriptreactjsreduxredux-form

解决方案


您所看到的发生是因为从技术上讲,两个 Topic 实例都是相同的“形式”。当您调用 时reduxForm(),您传入一个表单名称 ( wizard)。这充当表单的“标识符”,表单的数据使用此标识符存储在 redux 中。换句话说,当你有两个组件实例被渲染时,两个实例在 redux 中共享相同的表单状态。

解决这个问题的方法实际上取决于您的业务需求。您是否同时渲染多个主题?如果是这样,那么您可能想要查看FieldArrayFormSection。如果不是,那么在显示第二个主题表单之前,您的第一个主题表单的状态可能没有被破坏。


推荐阅读