Tôi đã viết một thành phần bao bọc có thể được sử dụng lại cho mục đích này dựa trên các câu trả lời được chấp nhận ở đây. Tuy nhiên, nếu tất cả những gì bạn cần làm là vượt qua một chuỗi, thì chỉ cần thêm thuộc tính dữ liệu và đọc nó từ e.target.dataset (như một số người khác đã đề xuất). Theo mặc định, trình bao bọc của tôi sẽ liên kết với bất kỳ prop nào là hàm và bắt đầu bằng 'bật' và tự động chuyển dữ liệu prop trở lại cho người gọi sau tất cả các đối số sự kiện khác. Mặc dù tôi chưa kiểm tra hiệu năng, nhưng nó sẽ cho bạn cơ hội để tránh tự tạo lớp và nó có thể được sử dụng như thế này:
const DataButton = withData('button')
const DataInput = withData('input');
hoặc cho các thành phần và chức năng
const DataInput = withData(SomeComponent);
hoặc nếu bạn thích
const DataButton = withData(<button/>)
tuyên bố rằng bên ngoài container của bạn (gần hàng nhập khẩu của bạn)
Đây là cách sử dụng trong một container:
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>
);
}
}
Đây là mã trình bao bọc '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;
}, {});
}