ฉันเขียนส่วนประกอบของ wrapper ที่สามารถนำกลับมาใช้ใหม่เพื่อจุดประสงค์นี้ซึ่งสร้างจากคำตอบที่ยอมรับได้ที่นี่ หากสิ่งที่คุณต้องทำคือส่งผ่านสตริงเพียงแค่เพิ่ม data-attribute และอ่านจาก e.target.dataset (เหมือนที่คนอื่น ๆ แนะนำ) โดยค่าเริ่มต้น wrapper ของฉันจะผูกติดกับเสาใด ๆ ที่เป็นฟังก์ชั่นและเริ่มต้นด้วย 'เปิด' และส่งเสาข้อมูลกลับไปยังผู้โทรโดยอัตโนมัติหลังจากที่มีข้อโต้แย้งเหตุการณ์อื่น ๆ ทั้งหมด แม้ว่าฉันจะไม่ได้ทดสอบประสิทธิภาพ แต่มันจะให้โอกาสคุณในการหลีกเลี่ยงการสร้างชั้นเรียนด้วยตัวเองและสามารถใช้ในลักษณะนี้:
const DataButton = withData('button')
const DataInput = withData('input');
หรือสำหรับส่วนประกอบและฟังก์ชั่น
const DataInput = withData(SomeComponent);
หรือถ้าคุณต้องการ
const DataButton = withData(<button/>)
ประกาศว่านอกภาชนะของคุณ (ใกล้การนำเข้าของคุณ)
นี่คือการใช้งานในคอนเทนเนอร์:
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>
);
}
}
นี่คือโค้ดของ 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;
}, {});
}