¿Cómo obtener el accesorio “clave” del elemento React (al cambiar)?

6 minutos de lectura

avatar de usuario de jimmy
palanqueta

Quiero obtener el valor y la clave de la opción cuando seleccione onChange.

Sé que puedo obtener opciones valor simplicidad utilizada event.target.value en onChangeOption función, pero ¿cómo puedo obtener key?

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

  • ¿Se siente cómodo creando un atributo personalizado para este caso? Como data-key?

    – Agney

    2 de noviembre de 2017 a las 9:05

Deberá pasar el valor en la clave como un accesorio diferente.

De documentos:

Las claves sirven como una pista para Reaccionar, pero no se pasan a sus componentes. Si necesita el mismo valor en su componente, páselo explícitamente como accesorio con un nombre diferente:

Leer: https://reactjs.org/docs/lists-and-keys.html

  • Esta es una mala respuesta. no propone una solución ni tiene en cuenta que se trata de un nativo select campo por lo que esto puede usarse en una forma de algún tipo que puede romperse si se reemplaza con un componente personalizado

    – cesar

    2 de noviembre de 2017 a las 9:04

  • Gracias por responder, he leído documentos, pero todavía tengo una pregunta. ¿Eso significa que “tengo que” pasar el valor en la clave como un apoyo diferente, para poder obtener la clave?

    – jimmy

    2 de noviembre de 2017 a las 9:04


  • Sí, significa eso.

    – Naishel Verdhan

    2 de noviembre de 2017 a las 9:38

Pasar la clave como accesorio funciona obviamente, pero una forma mucho más rápida podría ser incluir la clave como un atributo personalizado en su 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>

  • ¿Qué es el índice seleccionado aquí? event.target.options.selectedIndex;

    – program_bumble_bee

    22 de octubre de 2019 a las 10:11

  • En realidad, hay una mejor manera de acceder a estos data-* atributos, y se detalla aquí. En resumen, puedes usar element.dataset.<attribute_name> para obtener el valor del atributo. En este caso, haciendo event.target.options[selectedIndex].datasets.key también funciona

    – smac89

    04/01/2022 a las 23:20

Una forma sencilla de hacer esto es:

const functionCall = (event) => {
    console.log(event.target.getAttribute('a-key'));
}

<button a-key={1} onClick={functionCall}>Press Me</button>

Puse onClick pero puedes usar cualquier evento.

Puedes pasar cualquier cosa a través value. Creo que esto resuelve tu problema.

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

avatar de usuario de vsync
vsync

Imagina un componente como este:

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

Lo que representa una lista de entradas y entra en un data prop que es una colección (Formación de Objetos):

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

}

Como puedes ver, el key no se accede, pero se pasa a un función de curry que está manejando el almacenamiento en caché internamente, para evitar la creación “infinita” de funciones en las re-renderizaciones.

Avatar de usuario de Ayomide Oladipo
Ayomide Oladipo

¡Soy un principiante y tengo batalla con esto desde hace días! ¡Ahora, estaré feliz de compartirles mi respuesta final!

Esto es realmente fácil. ¡Todo lo que tienes que hacer es declarar una función anónima! para un onClick en el elemento que desea detectar su clave!

p.ej

data.map((item) => (<div
className = "newItem" key = {item.id} onClick = {() = displayKey(item.id)}
>{item.value}</div>))

entonces tu función puede ser así; mostrará cualquier “val” pasado en

const displayKey = (val) => {
    console.log(val)
}

¡Espero haber podido ayudar! luchar con un problema puede ser un dolor en el culo! Saludos cordiales .

avatar de usuario de caesay
cesarea

Por lo tanto, debe pasar la clave al <option> como apoyo, pero desde el <select> es un campo nativo y maneja los cambios internamente, se vuelve un poco difícil recuperar ese valor clave. Comencemos un problema a la vez, pasar el accesorio a la opción podría ser tan simple como envolver el componente de la opción así y usar el index prop como la nueva clave prop.

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

También tenga en cuenta que estamos creando un envoltorio de componente personalizado arriba para tragar el index apoyo de ser aplicado a <option /> en sí mismo, como reaccionar, no le gustan los accesorios desconocidos en los elementos dom.

Ahora, si pudiéramos manejar el evento seleccionado dentro de la opción, estaríamos listos, pero no podemos hacer eso. por lo que también debemos hacer una selección personalizada:

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

tiene dos accesorios valuey onChange. Observe que interceptamos el evento de cambio para encontrar el índice (la clave) y lo pasamos al padre como segundo parámetro. Esto no es muy bueno, pero no puedo pensar en otra manera fácil de hacerlo mientras sigo usando el nativo <select> elemento.

Tenga en cuenta que necesita reemplazar sus usos de <select> y <optoin> utilizar estas nuevas clases y asignar las index apoyo junto con el key apoyo en la opción.

  • Esto es genial, no había pensado en esto antes.

    – jimmy

    2 de noviembre de 2017 a las 10:07

¿Ha sido útil esta solución?