Ho scritto un componente wrapper che può essere riutilizzato per questo scopo e si basa sulle risposte accettate qui. Se devi solo passare una stringa, aggiungi un attributo di dati e leggilo da e.target.dataset (come alcuni altri hanno suggerito). Per impostazione predefinita, il mio wrapper si legherà a qualsiasi prop che è una funzione e inizia con 'on' e passa automaticamente il prop di dati al chiamante dopo tutti gli altri argomenti dell'evento. Anche se non l'ho testato per le prestazioni, ti darà l'opportunità di evitare di creare tu stesso la classe e può essere usato in questo modo:
const DataButton = withData('button')
const DataInput = withData('input');
o per componenti e funzioni
const DataInput = withData(SomeComponent);
o se preferisci
const DataButton = withData(<button/>)
dichiaralo all'esterno del tuo contenitore (vicino alle tue importazioni)
Ecco l'uso in un contenitore:
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>
);
}
}
Ecco il codice wrapper '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;
}, {});
}