如何使用react-bootstrap创建动态下拉列表?

40

在 react-bootstrap 网站的示例 code 中,显示如下。我需要使用数组来驱动选项,但是我找不到可以编译的示例。

<Input type="select" label="Multiple Select" multiple>
  <option value="select">select (multiple)</option>
  <option value="other">...</option>
</Input>
9个回答

49

你可以从这两个函数开始。第一个函数将根据传递给页面的属性动态创建选择选项。如果它们被映射到状态,则选择框将重新创建。

 createSelectItems() {
     let items = [];         
     for (let i = 0; i <= this.props.maxValue; i++) {             
          items.push(<option key={i} value={i}>{i}</option>);   
          //here I will be creating my options dynamically based on
          //what props are currently passed to the parent component
     }
     return items;
 }  

onDropdownSelected(e) {
    console.log("THE VAL", e.target.value);
    //here you will see the current selected value of the select input
}
在render方法中包含以下代码块。您将向onChange属性传递函数引用,每次调用onChange时,所选对象都会自动绑定到该函数。而不是手动编写选项,您只需调用createSelectItems()函数,它将基于某些约束条件(可能会改变)构建并返回选项。
  <Input type="select" onChange={this.onDropdownSelected} label="Multiple Select" multiple>
       {this.createSelectItems()}
  </Input>

很好的解释@Theo,我有一个功能请求,选择任何选项(仅单个值),它应该将相应选项的值附加到上面的输入框中,在我开始输入时,该选项应该打开。提前致谢! - Aashiq

24

我的工作示例

this.countryData = [
    { value: 'USA', name: 'USA' },
    { value: 'CANADA', name: 'CANADA' }            
];

<select name="country" value={this.state.data.country}>
    {this.countryData.map((e, key) => {
        return <option key={key} value={e.value}>{e.name}</option>;
    })}
</select>

3
我认为更正确的做法是省略 key(我认为它是数组索引),而是设置 <option key={e.value}>key 应该是组件的 id 引用,依赖于数组索引可能会导致不一致性,如果列表重新排序的话。 - Nathan
@Nathan - 正确。这篇文章详细介绍了...https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 - John Livermore

7

使用箭头函数绑定动态下拉菜单。

class BindDropDown extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      values: [
        { name: 'One', id: 1 },
        { name: 'Two', id: 2 },
        { name: 'Three', id: 3 },
        { name: 'four', id: 4 }
      ]
    };
  }
  render() {
    let optionTemplate = this.state.values.map(v => (
      <option value={v.id}>{v.name}</option>
    ));

    return (
      <label>
        Pick your favorite Number:
        <select value={this.state.value} onChange={this.handleChange}>
          {optionTemplate}
        </select>
      </label>
    );
  }
}

ReactDOM.render(
  <BindDropDown />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root">
    <!-- This element's contents will be replaced with your component. -->
</div>


6
// on component load, load this list of values
// or we can get this details from api call also    
const animalsList = [
{
    id: 1,
    value: 'Tiger'
}, {
    id: 2,
    value: 'Lion'
}, {
    id: 3,
    value: 'Dog'
}, {
    id: 4,
    value: 'Cat'
}
];

// generage select dropdown option list dynamically
function Options({ options }) {
    return (
        options.map(option => 
                    <option key={option.id} value={option.value}>                                   
                    {option.value}
                    </option>)
                   );
}

<select
name="animal"
className="form-control">
<Options options={animalsList} />
</select>

3
基本上你所需要做的就是映射数组。这将返回一个<option>元素列表,你可以把它放在表单中进行渲染。
array.map((element, index) => <option key={index}>{element}</option>)

完整的函数组件,从组件状态中保存的数组中呈现<option>Multiple属性允许您CTRL单击多个元素以进行选择。如果您想要下拉菜单,请删除它。
import React, { useState } from "react";

const ExampleComponent = () => {
    const [options, setOptions] = useState(["option 1", "option 2", "option 3"]);

    return (
        <form>
            <select multiple>
            { options.map((element, index) => <option key={index}>{element}</option>) }
            </select>
            <button>Add</button>
        </form>
    );
}

具有多选功能的组件

工作示例: https://codesandbox.io/s/blue-moon-rt6k6?file=/src/App.js


2
您需要为映射添加键,否则会出现警告,因为每个属性都应该有唯一的键。以下是修订后的代码:
let optionTemplate = this.state.values.map(
    (v, index) => (<option key={index} value={v.id}>{v.name}</option>)
);

2
一句话概括就是:
import * as YourTypes from 'Constants/YourTypes';
....
<Input ...>
    {Object.keys(YourTypes).map((t,i) => <option key={i} value={t}>{t}</option>)}
</Input>

假设您将列表常量存储在单独的文件中(除非它们是从Web服务下载的,否则您应该这样做):

# YourTypes.js
export const MY_TYPE_1="My Type 1"
....

1
您可以通过 map() 创建动态选择选项。
示例代码:
return (
    <select className="form-control"
            value={this.state.value}
            onChange={event => this.setState({selectedMsgTemplate: event.target.value})}>
        {
            templates.map(msgTemplate => {
                return (
                    <option key={msgTemplate.id} value={msgTemplate.text}>
                        Select one...
                    </option>
                )
            })
        }
    </select>
)
  </label>
);

0

我能够使用Typeahead来完成这个任务。虽然对于一个简单的场景来说看起来有点冗长,但我还是发布了它,因为它对某些人会有帮助。

首先,我创建了一个组件,以便它可以重复使用。

interface DynamicSelectProps {
    readonly id: string
    readonly options: any[]
    readonly defaultValue: string | null
    readonly disabled: boolean
    onSelectItem(item: any): any
    children?:React.ReactNode
}

export default function DynamicSelect({id, options, defaultValue, onSelectItem, disabled}: DynamicSelectProps) {

    const [selection, setSelection] = useState<any[]>([]);

    return <>
        <Typeahead
            labelKey={option => `${option.key}`}
            id={id}
            onChange={selected => {
                setSelection(selected)
                onSelectItem(selected)
            }}
            options={options}
            defaultInputValue={defaultValue || ""}
            placeholder="Search"
            selected={selection}
            disabled={disabled}
        />
    </>
}

回调函数

function onSelection(selection: any) {
    console.log(selection)
    //handle selection
}

使用方法

<div className="form-group">
    <DynamicSelect
        options={array.map(item => <option key={item} value={item}>{item}</option>)}
        id="search-typeahead"
        defaultValue={<default-value>}
        disabled={false}
        onSelectItem={onSelection}>
    </DynamicSelect>
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接