Escribí un componente contenedor que se puede reutilizar para este propósito que se basa en las respuestas aceptadas aquí. Sin embargo, si todo lo que necesita hacer es pasar una cadena, simplemente agregue un atributo de datos y léalo desde e.target.dataset (como han sugerido algunos otros). Por defecto, mi contenedor se unirá a cualquier accesorio que sea una función y comience con 'on' y automáticamente pasará el accesorio de datos al llamador después de todos los demás argumentos de evento. Aunque no lo he probado para el rendimiento, le dará la oportunidad de evitar crear la clase usted mismo, y se puede usar así:
const DataButton = withData('button')
const DataInput = withData('input');
o para componentes y funciones
const DataInput = withData(SomeComponent);
o si lo prefieres
const DataButton = withData(<button/>)
declarar que fuera de su contenedor (cerca de sus importaciones)
Aquí está el uso en un contenedor:
import withData from './withData';
const DataInput = withData('input');
export default class Container extends Component {
state = {
data: [
// ...
]
}
handleItemChange = (e, data) => {
// here the data is available
// ....
}
render () {
return (
<div>
{
this.state.data.map((item, index) => (
<div key={index}>
<DataInput data={item} onChange={this.handleItemChange} value={item.value}/>
</div>
))
}
</div>
);
}
}
Aquí está el código del contenedor 'withData.js:
import React, { Component } from 'react';
const defaultOptions = {
events: undefined,
}
export default (Target, options) => {
Target = React.isValidElement(Target) ? Target.type : Target;
options = { ...defaultOptions, ...options }
class WithData extends Component {
constructor(props, context){
super(props, context);
this.handlers = getHandlers(options.events, this);
}
render() {
const { data, children, ...props } = this.props;
return <Target {...props} {...this.handlers} >{children}</Target>;
}
static displayName = `withData(${Target.displayName || Target.name || 'Component'})`
}
return WithData;
}
function getHandlers(events, thisContext) {
if(!events)
events = Object.keys(thisContext.props).filter(prop => prop.startsWith('on') && typeof thisContext.props[prop] === 'function')
else if (typeof events === 'string')
events = [events];
return events.reduce((result, eventType) => {
result[eventType] = (...args) => thisContext.props[eventType](...args, thisContext.props.data);
return result;
}, {});
}