Я писал компонент с приведенным ниже кодом, который после рендеринга выглядит так:
Я использовал компоненты antd для визуализации полей. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу ни выбрать из поля выбора, ни написать в поле ввода, как показано ниже. У меня такое ощущение, что я использую React key
неуместно для mocFields
в методе рендеринга, полученном из getMOCField
.
import React, { Component } from "react";
import { Button, Icon, Select, Form, Input } from "antd";
const FormItem = Form.Item;
const Option = Select.Option;
import { FormComponentProps } from "antd/lib/form/Form";
type state = {
mocFields: JSX.Element[]
};
export class MOC extends Component<FormComponentProps, state> {
constructor(props) {
super(props);
this.state = {
mocFields: []
};
this.addMOCField = this.addMOCField.bind(this);
this.removeMOCField = this.removeMOCField.bind(this);
}
componentDidMount() {}
componentWillReceiveProps(nextProps) {}
removeMOCField(key, event: React.MouseEvent<HTMLElement>) {
event.preventDefault();
const { mocFields } = this.state;
mocFields.splice(key, 1);
this.setState({
mocFields
});
}
getMOCFieldFooter() {
return (
<div className="d-flex justify-content-between small">
<div className="inline-block">
<Button
type="primary"
shape="circle"
icon="plus"
ghost
size="small"
className="d-font mr-1"
onClick={this.addMOCField}
/>
<div
className="text-primary pointer d-font inline-block letter-spacing-1"
onClick={this.addMOCField}
>
Add another
</div>
<div className="d-font inline-block letter-spacing-1">or </div>
<div className="text-primary pointer d-font inline-block letter-spacing-1">
Create a new MOC
</div>
</div>
</div>
);
}
getMOCField(key) {
const { getFieldDecorator } = this.props.form;
return (
<div className="d-flex justify-content-between">
<div className="inline-block">
<FormItem label="Select MOC">
{getFieldDecorator(`selected_moc[${key}]`, {
rules: [
{
required: true,
message: "Please select moc"
}
]
})(
<Select>
<Option value={"A"}>A</Option>
<Option value={"B"}>B</Option>
</Select>
)}
</FormItem>
</div>
<div className="inline-block">
<FormItem label="Recovery (%)">
{getFieldDecorator(`recovery_percentage[${key}]`, {
rules: [
{
required: true,
message: "Please input the recovery percentage"
}
]
})(<Input type="number" step="0.000001" />)}
</FormItem>
</div>
<div className="inline-block pointer">
<span>
<Icon type="close" onClick={this.removeMOCField.bind(this, key)} />
</span>
</div>
</div>
);
}
addMOCField(event: React.MouseEvent<HTMLElement>) {
event.preventDefault();
const { mocFields } = this.state;
const MOCField = this.getMOCField(mocFields.length);
mocFields.push(MOCField);
this.setState({
mocFields
});
}
getAddMOCButton() {
return (
<div className="d-flex w-100 mt-3">
<Button
type="primary"
ghost
className="w-100"
onClick={this.addMOCField}
>
<Icon type="plus-circle" />
Add MOC
</Button>
</div>
);
}
render() {
const { mocFields } = this.state;
const mocButton = this.getAddMOCButton();
const toRender =
mocFields.length > 0 ? (
<div className="w-100 p-2 gray-background br-25">
{mocFields.map((f, index) => (
<div key={index}>{f}</div>
))}
{this.getMOCFieldFooter()}
</div>
) : (
mocButton
);
return toRender;
}
}
В чем может быть причина этого? Что я делаю неправильно? В настоящее время вышеуказанный компонент отображается следующим образом:
- Если число полей в
mocFields
равно нулю, отображается кнопка для добавления новых полей.
- После нажатия кнопки,
mocField
заполняется полем выбора и полем ввода, как показано выше. Ключ div
определяется во время метода рендеринга.