React HOC——将事件监听器添加到包装的组件
React HOC—add Event Listeners to wrapped Component
我正在尝试创建一个 HOC,它使常规功能组件 »Touchable«。
所以我有这样的 HOC:
const Touchable = (Component, handler) => {
const T = ({props, children}) => {
const Instance = React.createElement(
Component,
{
...props,
onTouchStart: (e) => handler.touchStart(e),
/*more listeners*/
}, children);
}
return T;
}
另一个像这样的组件:
const Button = ({props, children}) => <div>…</div>;
export default Touchable(Button, {touchStart: () => {}});
这样使用:
<Button>Hallo</Button>
结果在(反应开发人员面板):
<Button onTouchStart={…}>
<div>…</div>
</Button>
但我真正想要的是:
<Button>
<div onTouchStart={…}>…</div>
</Button>
我试过克隆实例,但不知何故我没有运气。我该怎么做?
您可以利用 React.cloneElement
克隆 children
并将自定义道具附加到它们
const Touchable = (Component, handler) => {
const T = ({props, children}) => {
const Instance = React.createElement(
Component,
props,
React.cloneElement(children, {
onTouchStart: (e) => handler.touchStart(e),
/*more listeners*/
});
)
}
return T;
}
你不能只 return Component
没有 React.createElement
部分吗?
类似于:
const TouchableHOC = (Component, handler) =>
(props) =>
<Component
{...props}
onClick={(event) => handler.touchStart(event)}
/>
const YourComponent = ({ children, onClick }) =>
<button onClick={onClick}>{children}</button>
const EnhancedComponent = TouchableHOC(
YourComponent,
{ touchStart: () => console.log('touchStart') }
)
const WithoutRest = TouchableHOC(
'button',
{ touchStart: () => console.log('touchStart') }
)
const App = () =>
<div>
<EnhancedComponent>
Click-me
</EnhancedComponent>
<WithoutRest>
No props at all
</WithoutRest>
</div>
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我正在尝试创建一个 HOC,它使常规功能组件 »Touchable«。
所以我有这样的 HOC:
const Touchable = (Component, handler) => {
const T = ({props, children}) => {
const Instance = React.createElement(
Component,
{
...props,
onTouchStart: (e) => handler.touchStart(e),
/*more listeners*/
}, children);
}
return T;
}
另一个像这样的组件:
const Button = ({props, children}) => <div>…</div>;
export default Touchable(Button, {touchStart: () => {}});
这样使用:
<Button>Hallo</Button>
结果在(反应开发人员面板):
<Button onTouchStart={…}>
<div>…</div>
</Button>
但我真正想要的是:
<Button>
<div onTouchStart={…}>…</div>
</Button>
我试过克隆实例,但不知何故我没有运气。我该怎么做?
您可以利用 React.cloneElement
克隆 children
并将自定义道具附加到它们
const Touchable = (Component, handler) => {
const T = ({props, children}) => {
const Instance = React.createElement(
Component,
props,
React.cloneElement(children, {
onTouchStart: (e) => handler.touchStart(e),
/*more listeners*/
});
)
}
return T;
}
你不能只 return Component
没有 React.createElement
部分吗?
类似于:
const TouchableHOC = (Component, handler) =>
(props) =>
<Component
{...props}
onClick={(event) => handler.touchStart(event)}
/>
const YourComponent = ({ children, onClick }) =>
<button onClick={onClick}>{children}</button>
const EnhancedComponent = TouchableHOC(
YourComponent,
{ touchStart: () => console.log('touchStart') }
)
const WithoutRest = TouchableHOC(
'button',
{ touchStart: () => console.log('touchStart') }
)
const App = () =>
<div>
<EnhancedComponent>
Click-me
</EnhancedComponent>
<WithoutRest>
No props at all
</WithoutRest>
</div>
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>