最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ANTD dynamic form - initial values - Stack Overflow

programmeradmin2浏览0评论

I have issue with setting initial values for antd dynamic form. Is there any way how to init values in dynamic for. It requires registered field using getFieldDecorator. But for dynamic fields, that field is not registered before.

I am getting this error: You cannot set field before registering it.

code:

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]
  };

  ponentDidMount() {
    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);

I have issue with setting initial values for antd dynamic form. Is there any way how to init values in dynamic for. It requires registered field using getFieldDecorator. But for dynamic fields, that field is not registered before.

I am getting this error: You cannot set field before registering it.

code: 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]
  };

  ponentDidMount() {
    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);
Share Improve this question edited Oct 26, 2018 at 15:00 Dawe asked Oct 26, 2018 at 14:07 DaweDawe 6101 gold badge11 silver badges19 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 2

You can use forceRender={true} in the prop that holding the form to render it. I had a form inside drawer. For that i had same error. Which I used forceRender={true} in drawer prop. So whichever holding the form, you need to render that using forceRender.

You should always register a field before you can use it. Here, I would suggest you to set the state with the list in ponentDidMount and then use initialValue to set the value in render. For example

ponentDidMount() {
  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>
}
发布评论

评论列表(0)

  1. 暂无评论