将事件监听器添加到React上下文中的引用。

huangapple go评论88阅读模式
英文:

Add event listener to ref from React context

问题

React上下文提供程序设置了一个ref,另一个组件使用它来设置一个模糊事件监听器。问题在于模糊事件不会触发监听器。

上下文提供程序的代码片段。

...
export function useEditorContext(): EditorContextProps {
    return useContext(EditorContext) as EditorContextProps;
}

export default function EditorProvider({ children }: { children: React.ReactNode }) {
    const ref = useRef<HTMLDivElement>(null);
    const historyState = useMemo(createEmptyHistoryState, []);
    const context = { historyState, ref };
    return (
        <EditorContext.Provider value={context}>
            <div ref={ref}>
                {children}
            </div>
        </EditorContext.Provider>
    );
}

目标是在词法插件中附加监听器。

const { historyState, ref } = useEditorContext();

const blurHandler = (event: FocusEvent) => {
    console.log('Blurred');
};

useEffect(() => {
    const element = ref.current;
    if (element) {
        element.addEventListener('blur', blurHandler, false);
    } else return;

    return () => {
        element.removeEventListener('blur', blurHandler);
    };
}, [ref.current]); // eslint-disable-line

我已经运行了带有日志记录的代码,并尝试了useRefaddEventListener的几种解决方案,但在上述情况下都没有起作用。欢迎任何建议!

英文:

The React context provider sets a ref that is used by another component to set a blur event listener. The problem is that a blur event does not trigger the listener.

Code extract for the context provider.

...
export function useEditorContext(): EditorContextProps {
    return useContext(EditorContext) as EditorContextProps;
}

export default function EditorProvider({ children }: { children: React.ReactNode }) {
    const ref = useRef&lt;HTMLDivElement&gt;(null);
    const historyState = useMemo(createEmptyHistoryState, []);
    const context = { historyState, ref };
    return (
        &lt;EditorContext.Provider value={context}&gt;
            &lt;div ref={ref}&gt;
                {children}
            &lt;/div&gt;
        &lt;/EditorContext.Provider&gt;
    );
}

The goal is to attach the listener in a Lexical plugin.

const { historyState, ref } = useEditorContext();

const blurHandler = (event: FocusEvent) =&gt; {
	console.log(&#39;Blurred&#39;);
};

useEffect(() =&gt; {
	const element = ref.current;
	if (element) {
		element.addEventListener(&#39;blur&#39;, blurHandler, false);
	} else return;

	return () =&gt; {
		element.removeEventListener(&#39;blur&#39;, blurHandler);
	};
}, [ref.current]); // eslint-disable-line

I have run the code with logging and tried several solutions/answers for useRef and addEventListener but none worked in the above scenario. Any suggestions are welcome!

答案1

得分: 1

模糊事件不会冒泡,但您可以使用相关的focusout事件来处理子元素失去焦点。

if (element) {
  element.addEventListener('focusout', blurHandler);
} else return;

return () => element.removeEventListener('focusout', blurHandler);
英文:

The blur event does not bubble, but you can use the related focusout event instead to handle child elements losing focus.

if (element) {
  element.addEventListener(&#39;focusout&#39;, blurHandler);
} else return;

return () =&gt; element.removeEventListener(&#39;focusout&#39;, blurHandler);

huangapple
  • 本文由 发表于 2023年5月26日 11:59:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76337581.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定