import { useRef, useState, useEffect } from 'react';
export const useHover = () => {
const [value, setValue] = useState(false);
const ref = useRef(null);
const handleMouseOver = () => setValue(true);
const handleMouseOut = () => setValue(false);
useEffect(
// eslint-disable-next-line consistent-return
() => {
const node = ref.current;
if (node) {
node.addEventListener('mouseover', handleMouseOver);
node.addEventListener('mouseout', handleMouseOut);
return () => {
node.removeEventListener('mouseover', handleMouseOver);
node.removeEventListener('mouseout', handleMouseOut);
};
}
},
[] // Recall only if ref changes
);
return [ref, value];
};
我的测试:
import { renderHook, act } from '@testing-library/react-hooks';
import { fireEvent, screen, render } from '@testing-library/react';
import React from 'react';
import { Box } from '@material-ui/core';
import { useHover } from './useHover';
describe('useHover', () => {
it('toogles', () => {
const { result } = renderHook(() => useHover());
const [ref, value] = result.current;
expect(value).toBeFalsy();
const Div = () => <Box ref={ref}>Test</Box>;
render(<Div />);
const Item = screen.getByText(/test/i);
act(() => {
fireEvent.mouseOver(Item);
expect(value).toBeTruthy();
});
act(() => {
fireEvent.mouseOut(Item);
expect(value).toBeFalsy();
});
});
});