如何在反应中使用 formik 创建动态下拉列表?

How to create dynamic drop down using formik in react?

我收到了来自 API 的 json 回复。

{
    "1": "Suits",
    "2": "Sarees",
    "3": "Footmats",
    "4": "Carpets",
    "5": "Sofa Covers"
}

我想使用这个 json 并使用 formik

在下拉列表中显示它
// Setting State
state = {
        itemType: {
            key: 0,
            value: 'Select'
        }
}

// Calling API in component did mount
componentDidMount() {
    axios.get('/itemTypes')
        .then(response => {
            this.setState({
                itemType: response.data
            });
            this.createItemType();
        }).catch(error => {
            console.log(error);
        });
}

// filling options values for drop down
createItemType = () => {
    let items = [];
    for (const [key, value] of Object.entries(this.state.itemType)) {
        items.push(<option key={key} value={key}>{value}</option>);
        //here I will be creating my options dynamically
    }
    return items;
}

// I have this field component to create drop down in <Formik> <Form> tag.
<Field name="itemType" className="form-control" component="select" placeholder="Item Type">
    {this.createItemType}
</Field>

我的目标是像这样创建动态值下拉列表

我在屏幕上看到的是

没有下拉菜单,只打印值。

如有任何帮助,我们将不胜感激

您收到错误消息是因为您的 Field 组件默认是 input 字段,不能有子项。如果你想让它成为一个 select 元素,你可以使用 as prop:

<Field
  className="form-control"
  as="select"
  onChange={this.onItemTypeDropdownSelected}
  name="itemType"
>
  <option>...</option>
</Field>

您在评论中提到实际上没有必要使用 Map,您想要的唯一原因是因为您来自 Java。如果您的键是字符串(如您的示例所示),则可以使用普通对象而不是 Map。但是,如果您想使用 Map,则可以像这样转换 JSON 对象,例如:

function objToMap(obj) {
  let map = new Map();

  for (let [key, value] of Object.entries(obj)) {
    map.set(key, value);
  }

  return map;
}

编辑:由于您不再使用地图,我更新了以下代码段:

state = {
  itemTypes: {},
};

componentDidMount() {
  axios
    .get('/itemTypes')
    .then((response) => {
      this.setState({
        itemTypes: response.data,
      });
      // you don't use this.createItemType() here 
      // just iterate over the state.itemTypes in render
    })
    .catch((error) => {
      console.log(error);
    });
};

render() {
  const options = [];
  for (let [key, value] of Object.entries(this.state.itemTypes)) {
    options.push(
      <option key={key} value={key}>
        {value}
      </option>
    );
  }

  return (
    <Field
      className="form-control"
      as="select"
      onChange={this.onItemTypeDropdownSelected}
      name="itemType"
    >
     {options}
    </Field>
  }