From c1c07ba1bb54ba7e7f6f53fc1d78245074f18200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Fri, 11 Aug 2023 16:57:25 +0200 Subject: [PATCH] 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 --- .../post_flag_icon/post_flag_icon.tsx | 176 ++++++++---------- 1 file changed, 79 insertions(+), 97 deletions(-) diff --git a/webapp/channels/src/components/post_view/post_flag_icon/post_flag_icon.tsx b/webapp/channels/src/components/post_view/post_flag_icon/post_flag_icon.tsx index 4e9ec027f2..544100ee7f 100644 --- a/webapp/channels/src/components/post_view/post_flag_icon/post_flag_icon.tsx +++ b/webapp/channels/src/components/post_view/post_flag_icon/post_flag_icon.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {useCallback, useEffect, useRef, useState} from 'react'; import {FormattedMessage} from 'react-intl'; import classNames from 'classnames'; @@ -19,115 +19,97 @@ export type Actions = { unflagPost: typeof unflagPost; } -interface Props { +type Props = { location?: keyof typeof Locations; postId: string; isFlagged: boolean; actions: Actions; } -interface State { - a11yActive: boolean; -} +const PostFlagIcon = ({ + actions: { + flagPost, + unflagPost, + }, + isFlagged, + postId, + location = Locations.CENTER, +}: Props) => { + const buttonRef = useRef(null); + const [a11yActive, setA11yActive] = useState(false); -export default class PostFlagIcon extends React.PureComponent { - static defaultProps = { - location: Locations.CENTER, - }; - - private buttonRef: React.RefObject; - - 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) => { + const handlePress = useCallback((e: React.MouseEvent) => { e.preventDefault(); - const { - actions, - isFlagged, - postId, - } = this.props; - if (isFlagged) { - actions.unflagPost(postId); + unflagPost(postId); } else { - actions.flagPost(postId); + flagPost(postId); } - }; + }, [flagPost, unflagPost, postId, isFlagged]); - handleA11yActivateEvent = () => { - this.setState({a11yActive: true}); - }; - - handleA11yDeactivateEvent = () => { - this.setState({a11yActive: false}); - }; - - render() { - const isFlagged = this.props.isFlagged; - - let flagIcon; - if (isFlagged) { - flagIcon = ; - } else { - flagIcon = ; + useEffect(() => { + function handleA11yActivateEvent() { + setA11yActive(true); + } + function handleA11yDeactivateEvent() { + setA11yActive(false); } - return ( - - - - } - > - - - ); + 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); + } + }; + }, []); + + useEffect(() => { + if (a11yActive && buttonRef.current) { + buttonRef.current.dispatchEvent(new Event(A11yCustomEventTypes.UPDATE)); + } + }, [a11yActive]); + + let flagIcon; + if (isFlagged) { + flagIcon = ; + } else { + flagIcon = ; } -} + + return ( + + + + } + > + + + ); +}; + +export default React.memo(PostFlagIcon);