Этот обернутый компонент должен знать, что handler.handleChange
выглядит неловко.
Если withSubscription
можно ограничить работой только с компонентами с состоянием, компонент может выставить changeHandler
ловушку:
function withSubscription(WrappedComponent) {
return class extends React.Component {
...
wrappedRef = React.createRef();
handleChange = (row) => {
if (typeof this.wrappedRef.current.changeHandler === "function") {
this.wrappedRef.current.changeHandler(row);
}
}
render() {
return <WrappedComponent ref={this.wrappedRef}{...this.props} />;
}
};
}
class MyGrid extends React.Component {
changeHandler = (row) => {
...
}
}
const GridWithSubscription = withSubscription(MyGrid);
Для работы с компонентами с отслеживанием состояния и без сохранения состояния withSubscription
следует сделать более обобщенным для взаимодействия с обернутым компонентом через реквизиты, т.е. зарегистрировать обратный вызов:
function withSubscription(WrappedComponent) {
return class extends React.Component {
handleChange = (row) => {
if (typeof this.changeHandler === "function") {
this.changeHandler(row);
}
}
registerChangeHandler = (cb) => {
this.changeHandler = cb;
}
render() {
return <WrappedComponent
registerChangeHandler={this.registerChangeHandler}
{...this.props}
/>;
}
};
}
class MyGrid extends React.Component {
constructor(props) {
super(props);
props.registerChangeHandler(this.changeHandler);
}
changeHandler = (row) => {
...
}
}
В случае, если приложение уже использует некоторую формуисточники событий, такие как субъекты RxJS, их можно использовать вместо handler.handleChange
для взаимодействия между родителем и ребенком:
function withSubscription(WrappedComponent) {
return class extends React.Component {
changeEmitter = new Rx.Subject();
handleChange = (row) => {
this.changeEmitter.next(row);
}
render() {
return <WrappedComponent
changeEmitter={this.changeEmitter}
{...this.props}
/>;
}
};
}
class MyGrid extends React.Component {
constructor(props) {
super(props);
this.props.changeEmitter.subscribe(this.changeHandler);
}
componentWillUnmount() {
this.props.changeEmitter.unsubscribe();
}
changeHandler = (row) => {
...
}
}
Передача объектов / источников событий для этой цели распространена в Angular, поскольку зависимость от RxJSуже навязано рамками.