如何从 React / Typescript 应用程序中的 select 选项选择中获取额外数据

How to obtain additional data from select options choice in React / Typescript app

我有一系列交易所,一旦用户选择了一个交易所,我想同时使用交易所的名称和它的基本报价。

例如,如果用户选择下面的第一个选项,我想捕获 "poloniex" 以及基本键 "USDC"

首先我尝试使用这个:

{exchanges.map((exchange, i) =>
  (<option key={i} value={exchange.exchange} base={exchange.quote}>
    {capFirst(exchange.exchange)} ({exchange.quote}) ${exchange.price_quote}
  </option>))}

但是我收到 base 不存在的错误,但是我不能向选项添加任何属性吗?如果它在 JSX 中,也许不是? data 也没有用。

Type '{ children: string[]; key: number; value: string; base: string; }' is not assignable to type 'DetailedHTMLProps, HTMLOptionElement>'. Property 'base' does not exist on type 'DetailedHTMLProps, HTMLOptionElement>'.ts(2322)

我尝试的另一种方法是获取所选选项的索引键,但是下面的代码会生成 key = null.

下面target.value会给我它的值,但我还需要基本报价。

@bind
handleExchangeSelect(event: React.FormEvent<HTMLSelectElement>) {
  const { exchanges } = this.props;
  const target = event.target as HTMLSelectElement;
  console.log('target', target);
  const exchange = target.value;
  const key = target.getAttribute('key');
  console.log('exchange', exchange);
  console.log('key', key);
  // if (key) {
  //   console.log(exchanges[Number(key)]);
  // }
  this.setState({
    exchange,
    // exchange_base: base ? base : ''
  });
}

我希望有一种更明显、更简洁的方法,但我发现了这个并且它有效:

https://reactjs.org/docs/forms.html

Note

You can pass an array into the value attribute, allowing you to select multiple options in a select tag:

<select multiple={true} value={['B', 'C']}>

我的应用中的解决方案

select选项

{exchanges.map((exchange, i) =>
  (<option key={i} value={[exchange.exchange, exchange.quote]}>
    {capFirst(exchange.exchange)} ({exchange.quote}) ${exchange.price_quote}
  </option>))}

select处理程序

@bind
handleExchangeSelect(event: React.FormEvent<HTMLSelectElement>) {
  const target = event.target as HTMLSelectElement;
  const exchangeValues = target.value.split(',');
  const exchange = exchangeValues[0];
  const exchange_base = exchangeValues[1];
  console.log('exchange', exchange);
  console.log('exchange_base', exchange_base);
  this.setState({
    exchange,
    exchange_base
  });
}

这让我得到了我想要的东西:

{ 
  exchange: 'gdax',
  exchange_base: 'USD'
}

解决这个问题的反应方法是创建一个自己的 select 组件,它看起来像这样:

class ExchangeSelect extends Component {
    handleSelect = event => {
        const {exchanges, onSelect} = this.props;
        const selected = exchanges.find(exchange => exchange.exchange === event.target.value);
        onSelect(selected);
    };

    render() {
        const {exchanges} = this.props;

        return (
            <select onChange={this.handleSelect}>
                {exchanges.map(exchange => (
                    <option key={exchange.exchange} value={exchange.exchange}>
                        {exchange.exchange} ({exchange.quote}) ${exchange.price_quote}
                    </option>
                ))}
            </select>
        );
    }
}

exchanges 是交换对象的列表,您可以这样使用它:

const exchanges = [
    {exchange: 'poloniex', quote: 'USDC', price_quote: '0.42'},
    {exchange: 'bitibu', quote: 'USDT', price_quote: '0.666'},
    {exchange: 'bittrex', quote: 'USDT', price_quote: '0.21'},
];

在渲染()中:

<ExchangeSelect 
    exchanges={exchanges} 
    onSelect={exchange => console.log(exchange.quote)} 
/>

实例: