Как получить "ключевую" опору из элемента React (при изменении)?

Я хочу получить значение параметра и ключ при выборе onChange.

Я знаю, что могу получить простоту значения параметра, используемую event.target.value в функции onChangeOption, но как я могу получить key?

<select onChange={this.onChangeOption} value={country}>
    {countryOptions.map((item, key) =>
        <option key={key} value={item.value}>
            {item.name}
        </option>
    )}
</select>

Ответ 1

Очевидно, что передача ключа в качестве опоры работает, но гораздо более быстрым способом может быть включение ключа в качестве пользовательского атрибута в ваш html.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.onSelect = this.onSelect.bind(this);
  }
  onSelect(event) {
    const selectedIndex = event.target.options.selectedIndex;
        console.log(event.target.options[selectedIndex].getAttribute('data-key'));
  }

  render() {
    return ( 
      <div>
      <select onChange = {this.onSelect}>
       <option key="1" data-key="1">One</option> 
       <option key="2" data-key="2">Two</option>             </select> 
     </div>
    );
  }
}

ReactDOM.render( < App / > , 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"></div>

Ответ 2

Вам нужно будет передать значение в качестве другой опоры.

Из документов:

Ключи служат подсказкой для Реагирования, но они не передаются вашим компонентам. Если вам нужно то же самое значение в вашем компоненте, пропустите его явно как опору с другим именем:

Читайте: https://reactjs.org/docs/lists-and-keys.html

Ответ 3

Поэтому вам нужно передать ключ в <option> как опору, но поскольку <select> является родным полем и обрабатывает изменения внутри, ему становится немного сложно получить это значение ключа. Позволяет запускать одну проблему за раз, передавая опцию в опцию, может быть так же просто, как обертывание компонента опции, например, и использование index в качестве нового ключа.

const CustomOption = ({ value, children, index }) => (
    <option key={index} value={value}>{value}</option>
);

Также обратите внимание, что мы создаем специальную оболочку компонента выше, чтобы усвоить index от применения к <option/> так как реакция не похожа на неизвестные реквизиты на элементы dom.

Теперь, если бы мы могли обработать выбранное событие внутри опции, мы бы это сделали, но мы не можем этого сделать. поэтому нам нужно сделать также индивидуальный выбор:

class CustomSelect extends React.Component {

    static propTypes = {
        value: PropTypes.object,
        onChange: PropTypes.func,
    }

    handleChanged = (e) => {
        const newValue = e.target.value;
        let newKey;

        // iterate through our children searching for the <CustomOption /> that was just selected
        React.children.forEach(this.children, (c) => {
            if (c.props && c.props.index && c.props.value === newValue) {
                newKey = c.props.key;
            }
        });

        this.props.onChange(e, newKey);
    }

    render() {
        return (
            <select value={this.props.value} onChange={this.handleChanged}>
                {this.props.children}
            </select>
        );
    }
}

он имеет два value реквизита и onChange. Обратите внимание, что мы перехватываем событие изменения, чтобы найти индекс (ключ), и мы передаем его родительскому в качестве второго параметра. Это не очень приятно, но я не могу придумать еще один простой способ сделать это, все еще используя собственный <select> элемент.

Обратите внимание, что вам нужно заменить ваши обычаи <select> и <optoin> чтобы использовать эти новые классы, и назначить index вместе с key словом в опции.

Ответ 4

Вы можете передавать что-либо через value. Я думаю, что это решает вашу проблему.

<select onChange={this.handleChange}>
        {this.state.countryOptions.map((item, key) =>
          <option key={key} 
            value={JSON.stringify({key, value:item.value})}>
            //passing index along with value
            {item.value}
          </option>
        )}
</select>

handleChange(e) {
    let obj = JSON.parse(e.target.value) 
   // gives object{ key:country index, value: country value}
  }

Ответ 5

Представьте себе такой компонент:

<Component data={[{id:'a23fjeZ', name="foo"}, ...]}' 

Который отображает список входных данных и получает реквизит data, который является коллекцией (массив объектов):

function Component ( props ){
    // cached handler per unique key. A self-invoked function with a "cache" object
    const onChange = (cache => param => {
        if( !cache[param] )
            cache[param] = e => 
                console.log(param, e.target.name, e.target.value)

        return cache[param];
    }
    )({});

    return props.data.map(item =>
        <input key={item.id} name={item.name} onChange={onChange(item.id)} />
    }

}

Как вы можете видеть, к key не обращаются, а передают в каррирующую функцию, которая обрабатывает внутреннее кэширование, чтобы предотвратить "бесконечное" создание функций при повторном рендеринге. ,