Skip to content

Commit 930f041

Browse files
author
berdysheva
committed
fix(NavigationPopup): use react-hook
1 parent 0f7a212 commit 930f041

File tree

3 files changed

+44
-62
lines changed

3 files changed

+44
-62
lines changed

src/components/navigation/components/Header/Header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Control from '../../../Control/Control';
66

77
import Logo from '../Logo/Logo';
88

9-
import {HeaderData, NavigationLogo} from '../../../../models/navigation';
9+
import {HeaderData, NavigationLogo} from '../../../../models';
1010
import Navigation from '../Navigation/Navigation';
1111
import MobileNavigation from '../MobileNavigation/MobileNavigation';
1212
import NavigationItem from '../NavigationItem/NavigationItem';

src/components/navigation/components/NavigationItem/NavigationItem.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
}
2626

2727
&__icon {
28+
display: flex;
2829
width: 20px;
2930
height: 20px;
3031
margin-right: $indentXXXS;
Lines changed: 42 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import _ from 'lodash';
22
import block from 'bem-cn-lite';
3-
import React, {Fragment, createRef, RefObject} from 'react';
3+
import React, {Fragment, useRef, useState, useEffect, useCallback} from 'react';
44
import {Portal} from '@gravity-ui/uikit';
55

66
import {OutsideClick} from '../../../index';
7-
import {NavigationLinkItem} from '../../../../models/navigation';
7+
import {NavigationLinkItem} from '../../../../models';
88
import NavigationItem from '../NavigationItem/NavigationItem';
99

1010
import './NavigationPopup.scss';
@@ -18,73 +18,54 @@ export interface NavigationPopupProps {
1818
className?: string;
1919
}
2020

21-
interface NavigationPopupState {
22-
calculatedLeft?: number;
23-
}
24-
25-
export default class NavigationPopup extends React.Component<
26-
NavigationPopupProps,
27-
NavigationPopupState
28-
> {
29-
ref: RefObject<HTMLDivElement> = createRef();
30-
state = {
31-
calculatedLeft: this.props.left,
32-
};
33-
34-
private calculateLeft = _.debounce(() => {
35-
const {left} = this.props;
21+
export const NavigationPopup: React.FC<NavigationPopupProps> = ({items, left, onClose}) => {
22+
const [calculatedLeft, setCalculatedLeft] = useState(left);
23+
const popupRef = useRef<HTMLDivElement>(null);
3624

37-
if (this.ref && this.ref.current && left) {
38-
const right = left + this.ref.current.offsetWidth;
25+
const calculateLeft = useCallback(() => {
26+
if (popupRef && popupRef.current && left) {
27+
const right = left + popupRef.current.offsetWidth;
3928
const docWidth = document.body.clientWidth;
40-
const calculatedLeft = right > docWidth ? left - (right - docWidth) : left;
41-
this.setState({calculatedLeft});
29+
const currentLeft = right > docWidth ? left - (right - docWidth) : left;
30+
setCalculatedLeft(currentLeft);
4231
} else {
43-
this.setState({calculatedLeft: left});
32+
setCalculatedLeft(left);
4433
}
45-
}, 100);
34+
}, [left]);
4635

47-
componentDidMount() {
48-
this.calculateLeft();
49-
window.addEventListener('resize', this.calculateLeft);
50-
}
36+
useEffect(() => {
37+
const debounceCalculateLeft = _.debounce(calculateLeft, 100);
38+
calculateLeft();
39+
window.addEventListener('resize', debounceCalculateLeft);
5140

52-
componentDidUpdate(prevProps: NavigationPopupProps) {
53-
if (prevProps.left !== this.props.left) {
54-
this.calculateLeft();
55-
}
56-
}
41+
return () => {
42+
window.removeEventListener('resize', debounceCalculateLeft);
43+
};
44+
}, [calculateLeft]);
5745

58-
componentWillUnmount() {
59-
window.removeEventListener('resize', this.calculateLeft);
60-
}
46+
useEffect(() => {
47+
calculateLeft();
48+
}, [calculateLeft, left]);
6149

62-
render() {
63-
if (!document || !document.body) {
64-
return null;
65-
}
50+
if (!document || !document.body) {
51+
return null;
52+
}
6653

67-
const {onClose} = this.props;
68-
const {calculatedLeft} = this.state;
54+
const renderDefaultPopup = (
55+
<Fragment>
56+
{items.map((item) => (
57+
<NavigationItem key={item.text} className={b('link')} data={item} />
58+
))}
59+
</Fragment>
60+
);
6961

70-
return (
71-
<Portal>
72-
<div ref={this.ref} className={b()} style={{left: calculatedLeft}}>
73-
<OutsideClick onOutsideClick={onClose}>
74-
{this.renderDefaultPopup()}
75-
</OutsideClick>
76-
</div>
77-
</Portal>
78-
);
79-
}
62+
return (
63+
<Portal>
64+
<div ref={popupRef} className={b()} style={{left: calculatedLeft}}>
65+
<OutsideClick onOutsideClick={onClose}>{renderDefaultPopup}</OutsideClick>
66+
</div>
67+
</Portal>
68+
);
69+
};
8070

81-
private renderDefaultPopup() {
82-
return (
83-
<Fragment>
84-
{this.props.items.map((item) => (
85-
<NavigationItem key={item.text} className={b('link')} data={item} />
86-
))}
87-
</Fragment>
88-
);
89-
}
90-
}
71+
export default NavigationPopup;

0 commit comments

Comments
 (0)