admin管理员组

文章数量:1415420

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

本文标签: javascriptANTD dynamic forminitial valuesStack Overflow