[英]Add event listener to every Component with a given property
我有很多帶有onKeyup
事件監聽器的組件,然后檢查鍵是否是Tab
,如果是,則采取行動。 我想稍微抽象一下並創建一個onTab
屬性,其中的值是執行該操作的回調 function。 但是,重要的是,我想要“這個鍵是Tab
嗎?” 抽象出來的邏輯。 我的想法是我可以編寫這樣的邏輯:“在初始化此組件時,檢查它是否具有onTab
屬性,如果有,則使用 X 邏輯創建一個onKeyup
事件偵聽器以觸發onTab
回調。” 但是,我不確定該怎么做。
任何人都可以幫忙嗎?
我可以想到 3 種解決方案,每種都有其優點和復雜性。
首先,使用鈎子:
// use-on-tab.js
const useOnTab = function (callback) {
let listener = function (event) {
if (event.code === 'Enter') {
callback()
}
}
return listener
}
export default useOnTab
// Foo.js
import useOnTab from './use-on-tab'
const Foo = function () {
let onTab = useOnTab(() => console.log('foo'))
return <div onKeyUp={onTab} tabIndex="0">Foo</div>
}
export default Foo
這個方案很簡單,可以隱藏檢查key的邏輯,只通過回調。 但是您仍然必須手動調用useOnTab
並在每個組件上添加onKeyUp
屬性。
二、使用HOC:
// with-on-tab.js
const withOnTab = function (WrappedComponent) {
let createListener = function (callback) {
return function (event) {
if (event.code === 'Enter') {
callback()
}
}
}
return function ({ onTab, ...props }) {
return <WrappedComponent {...props} onKeyUp={createListener(onTab)} />
}
}
export default withOnTab
// Bar.js
import withOnTab from './with-on-tab'
const Bar = function (props) {
return <div tabIndex="0" {...props}>Bar</div>
}
export default withOnTab(Bar)
<Bar onTab={() => console.log('bar')} />
閱讀有關高階組件的更多信息。
最后一個是自定義 JSX:
// jsx-dev-runtime.js
import * as ReactJSXRuntimeDev from 'react/jsx-dev-runtime'
export const Fragment = ReactJSXRuntimeDev.Fragment
export function jsxDEV(
type,
props,
key,
isStaticChildren,
source,
self
) {
let newProps = props
if (Object.prototype.hasOwnProperty.call(props, 'onTab')) {
let { onTab, ...props } = newProps
newProps = {
...props,
onKeyUp: event => {
if (event.code === 'Enter') {
onTab()
}
}
}
}
return ReactJSXRuntimeDev.jsxDEV(
type,
newProps,
key,
isStaticChildren,
source,
self
)
}
// Baz.js
const Baz = function (props) {
return <div tabIndex="0" {...props}>Baz</div>
}
export default Baz
/** @jsxImportSource custom-jsx-library */
<Baz onTab={() => console.log('baz')} />
我從@emotion/react
得到這個想法,它必須處理css
道具。 Github
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.