我有一个绝对可以正常工作的组件,我正在尝试使用笑话和酶编写一些测试。
const handleEvent = (e: KeyboardEvent) => {
if(e.keyCode === 27)
console.log('Escape event');
}
const Component = () => {
const ref = useRef(null);
useEffect(() => {
ref.current?.addEventListener('keydown', handleEvent);
return () => {
ref.current?.removeEventListener('keydown', handleEvent);
}
}, []);
return (
<div ref={ref}> Some inner elements </div>
)
}
这是我试图模拟转义事件的测试
it('simulate escape event', () => {
const component = mount(<Component />);
component.simulate('keydown', { keyCode: 27 });
// assertion of things that are handled on escape
});
这不会触发转义事件。但是,当我将事件处理程序直接附加到dom上的组件时,相同的测试正在模拟转义事件,并且似乎运行良好。
const handleEvent = (e: KeyboardEvent) => {
if(e.keyCode === 27)
console.log('Escape event');
}
const Component = () => {
const ref = useRef(null);
return (
<div ref={ref} onKeyDown={handleEvent}> Some inner elements </div>
)
}
有人可以告诉我为什么将事件动态附加到组件时,模拟无法正常工作,但是直接将其添加到dom时,可以正常工作吗?我尝试在各种文章中搜索此术语,但一无所获。预先感谢。
将Empty数组依赖项删除为useEffect。然后就可以了
useEffect(() => {
ref.current?.addEventListener('keydown', handleEvent);
return () => {
ref.current?.removeEventListener('keydown', handleEvent);
}
});
您仅将eventHandler附加在组件的安装上。
但是DOM元素可能会在react渲染之间改变,因此您实际上应该在所有useEffects中附加eventListener,这是在react渲染和react生命周期中的DOM更新之后触发的。
如果您认为DOM元素上会有昂贵的东西,并且不希望它在每个useEffects上运行,您也可以依靠callBackRefs。
对于仅附加事件侦听器,这种没有依赖项数组的useEffect应该没问题。
此外,.simulate(“ click”)的代码实际上会寻找onClick函数并将参数传递给它,没有“实际”单击发生]]
因此,如果酶不模拟触发器……您可能必须自己派遣Eventcomponent.getDOMNode()以获取应该在其上运行dispatchEvent的DOM节点。