Migrate components/post_view/post_flag_icon/post_flag_icon.tsx from class to function component (#24187)

* Class to functional example 3

* Address feedback

* Address feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Daniel Espino García
2023-08-11 16:57:25 +02:00
коммит произвёл GitHub
родитель 544ceeba3e
Коммит c1c07ba1bb

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React, {useCallback, useEffect, useRef, useState} from 'react';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
@@ -19,79 +19,60 @@ export type Actions = {
unflagPost: typeof unflagPost; unflagPost: typeof unflagPost;
} }
interface Props { type Props = {
location?: keyof typeof Locations; location?: keyof typeof Locations;
postId: string; postId: string;
isFlagged: boolean; isFlagged: boolean;
actions: Actions; actions: Actions;
} }
interface State { const PostFlagIcon = ({
a11yActive: boolean; actions: {
} flagPost,
unflagPost,
export default class PostFlagIcon extends React.PureComponent<Props, State> { },
static defaultProps = {
location: Locations.CENTER,
};
private buttonRef: React.RefObject<HTMLButtonElement>;
constructor(props: Props) {
super(props);
this.buttonRef = React.createRef();
this.state = {
a11yActive: false,
};
}
componentDidMount() {
if (this.buttonRef.current) {
this.buttonRef.current.addEventListener(A11yCustomEventTypes.ACTIVATE, this.handleA11yActivateEvent);
this.buttonRef.current.addEventListener(A11yCustomEventTypes.DEACTIVATE, this.handleA11yDeactivateEvent);
}
}
componentWillUnmount() {
if (this.buttonRef.current) {
this.buttonRef.current.removeEventListener(A11yCustomEventTypes.ACTIVATE, this.handleA11yActivateEvent);
this.buttonRef.current.removeEventListener(A11yCustomEventTypes.DEACTIVATE, this.handleA11yDeactivateEvent);
}
}
componentDidUpdate() {
if (this.state.a11yActive && this.buttonRef.current) {
this.buttonRef.current.dispatchEvent(new Event(A11yCustomEventTypes.UPDATE));
}
}
handlePress = (e: React.MouseEvent) => {
e.preventDefault();
const {
actions,
isFlagged, isFlagged,
postId, postId,
} = this.props; location = Locations.CENTER,
}: Props) => {
const buttonRef = useRef<HTMLButtonElement>(null);
const [a11yActive, setA11yActive] = useState(false);
const handlePress = useCallback((e: React.MouseEvent) => {
e.preventDefault();
if (isFlagged) { if (isFlagged) {
actions.unflagPost(postId); unflagPost(postId);
} else { } else {
actions.flagPost(postId); flagPost(postId);
}
}, [flagPost, unflagPost, postId, isFlagged]);
useEffect(() => {
function handleA11yActivateEvent() {
setA11yActive(true);
}
function handleA11yDeactivateEvent() {
setA11yActive(false);
}
if (buttonRef.current) {
buttonRef.current.addEventListener(A11yCustomEventTypes.ACTIVATE, handleA11yActivateEvent);
buttonRef.current.addEventListener(A11yCustomEventTypes.DEACTIVATE, handleA11yDeactivateEvent);
}
return () => {
if (buttonRef.current) {
buttonRef.current.removeEventListener(A11yCustomEventTypes.ACTIVATE, handleA11yActivateEvent);
buttonRef.current.removeEventListener(A11yCustomEventTypes.DEACTIVATE, handleA11yDeactivateEvent);
} }
}; };
}, []);
handleA11yActivateEvent = () => { useEffect(() => {
this.setState({a11yActive: true}); if (a11yActive && buttonRef.current) {
}; buttonRef.current.dispatchEvent(new Event(A11yCustomEventTypes.UPDATE));
}
handleA11yDeactivateEvent = () => { }, [a11yActive]);
this.setState({a11yActive: false});
};
render() {
const isFlagged = this.props.isFlagged;
let flagIcon; let flagIcon;
if (isFlagged) { if (isFlagged) {
@@ -119,15 +100,16 @@ export default class PostFlagIcon extends React.PureComponent<Props, State> {
} }
> >
<button <button
ref={this.buttonRef} ref={buttonRef}
id={`${this.props.location}_flagIcon_${this.props.postId}`} id={`${location}_flagIcon_${postId}`}
aria-label={isFlagged ? localizeMessage('flag_post.unflag', 'Remove from Saved').toLowerCase() : localizeMessage('flag_post.flag', 'Save').toLowerCase()} aria-label={isFlagged ? localizeMessage('flag_post.unflag', 'Remove from Saved').toLowerCase() : localizeMessage('flag_post.flag', 'Save').toLowerCase()}
className='post-menu__item' className='post-menu__item'
onClick={this.handlePress} onClick={handlePress}
> >
{flagIcon} {flagIcon}
</button> </button>
</OverlayTrigger> </OverlayTrigger>
); );
} };
}
export default React.memo(PostFlagIcon);