ANTD动态形式-初始值

时间:2018-10-26 14:07:14

标签: javascript reactjs forms dynamic antd

我在设置antd动态表单的初始值时遇到问题。有什么方法可以在动态中初始化值。它要求使用getFieldDecorator注册字段。但是对于动态字段,该字段之前未注册。

我收到此错误: You cannot set field before registering it.

代码:https://codesandbox.io/s/jnx3p1nz5

import React from "react";
import { Select, Icon, Button, Form, Input } from "antd";

const FormItem = Form.Item;
const TextArea = Input.TextArea;
const Option = Select.Option;

const SELECT = ['opt1', 'opt2'];

class TestForm extends React.Component {
  state = {
    listKeys: [0]
  };

  componentDidMount() {
    const {
      form: { setFieldsValue }
    } = this.props;


    // WORK
    // setFieldsValue({
    //   name: 'test',
    // });

    // setFieldsValue({
    //   name: 'test',
    //   list: [
    //     {
    //       sub1: 'test1',
    //       sub2: 'test2',
    //     }
    //   ]
    // });

    // !!!!!!!!!!!! NOT WORK
    // setFieldsValue({
    //   name: 'test',
    //   list: [
    //     {
    //       sub1: 'test1',
    //       sub2: 'opt2'
    //     },
    //     {
    //       sub1: 'test11',
    //       sub2: 'opt1'
    //     }
    //   ]
    // });

    setFieldsValue({
      name: 'test',
      list: [
        {
          sub1: 'test1',
          sub2: 'opt2',
          opt2sub: 'bla',
        },
        {
          sub1: 'test11',
          sub2: 'opt1'
        },
        {
          sub1: 'test3',
          sub2: 'opt2',
          opt2sub: 'bla',
        },
      ]
    });
  }

  remove = k => {
    const { listKeys } = this.state;

    if (listKeys.length === 1) {
      return;
    }

    this.setState({
      listKeys: listKeys.filter(key => key !== k)
    });
  };

  add = () => {
    const { listKeys } = this.state;

    this.setState({
      listKeys: [...listKeys, listKeys.length]
    });
  };

  render() {
    const {
      form: { getFieldDecorator, getFieldValue }
    } = this.props;
    const { listKeys } = this.state;

    return (
      <Form onSubmit={this.handleSubmit}>
        <FormItem label="Name">
          {getFieldDecorator("name")(<Input placeholder="name" />)}
        </FormItem>
        {listKeys.map((key, index) => {
          const type = getFieldValue(`list[${key}].sub2`);

          return (
            <div key={key}>
              <FormItem label="Sub1">
                {getFieldDecorator(`list[${key}].sub1`)(
                  <Input placeholder="Sub1" />
                )}
              </FormItem>
              <FormItem label="Sub2">
                {getFieldDecorator(`list[${key}].sub2`,{
                  initialValue: 'opt1'
                })(
                  <Select>
                    {SELECT.map(item => <Option key={item} value={item}>{item}</Option> )}
                  </Select>
                )}
              </FormItem>
              {type === 'opt2' && (
                <FormItem label="opt2sub">
                  {getFieldDecorator(`list[${key}].opt2sub`)(
                    <Input placeholder="opt2sub" />
                  )}
                </FormItem>
              )}
              {index > 0 && (
                <Icon
                  className="dynamic-delete-button"
                  type="minus-circle-o"
                  onClick={() => this.remove(key)}
                />
              )}
            </div>
          );
        })}
        <FormItem>
          <Button type="dashed" onClick={this.add}>
            <Icon type="plus" />Add field
          </Button>
        </FormItem>
        <FormItem>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </FormItem>
      </Form>
    );
  }
}

export default Form.create()(TestForm);

2 个答案:

答案 0 :(得分:1)

您可以在持有表单的道具中使用forceRender={true}进行呈现。我在抽屉里有一张表格。为此,我有同样的错误。我在抽屉道具中使用了forceRender={true}。因此,无论使用哪种形式的表单,都需要使用forceRender来呈现。

答案 1 :(得分:0)

使用该字段之前,应始终注册一个字段。在这里,我建议您使用componentDidMount中的列表设置状态,然后使用initialValue设置render中的值。例如

componentDidMount() {
  const {
    form: { setFieldsValue },
    listKeys,
  } = this.props;
  this.setState({listKeys})
}

render() {
  <FormItem label="Sub1">
    {getFieldDecorator(`list[${key}].sub1`, {initialValue: this.props.list[key].sub1})(
      <Input placeholder="Sub1" />
    )}
  </FormItem>
}