From a18e2715eae01b82f516124200380664a52fe7c5 Mon Sep 17 00:00:00 2001 From: Danil Valov Date: Wed, 11 Sep 2024 16:28:45 +0300 Subject: [PATCH] Rewrite `GiftedAvatar` class component to functional component + remove `defaultProps` --- src/Avatar.tsx | 2 +- src/GiftedAvatar.tsx | 178 +++++++++++++++++++++---------------------- src/GiftedChat.tsx | 2 +- 3 files changed, 89 insertions(+), 93 deletions(-) diff --git a/src/Avatar.tsx b/src/Avatar.tsx index 25031d34a..216421690 100644 --- a/src/Avatar.tsx +++ b/src/Avatar.tsx @@ -7,7 +7,7 @@ import { View, ViewStyle, } from 'react-native' -import GiftedAvatar from './GiftedAvatar' +import { GiftedAvatar } from './GiftedAvatar' import { StylePropType, isSameUser, isSameDay } from './utils' import { IMessage, LeftRightStyle, User } from './Models' diff --git a/src/GiftedAvatar.tsx b/src/GiftedAvatar.tsx index ef29d81d8..f6226244e 100644 --- a/src/GiftedAvatar.tsx +++ b/src/GiftedAvatar.tsx @@ -1,5 +1,5 @@ import PropTypes from 'prop-types' -import React from 'react' +import React, { useCallback, useRef } from 'react' import { Image, Text, @@ -51,38 +51,32 @@ export interface GiftedAvatarProps { onLongPress?: (props: GiftedAvatarProps) => void } -export default class GiftedAvatar extends React.Component { - static defaultProps = { - user: { +export function GiftedAvatar ( + props: GiftedAvatarProps +) { + const avatarNameRef = useRef(undefined) + const avatarColorRef = useRef(undefined) + + const { + user = { name: null, avatar: null, }, - onPress: undefined, - onLongPress: undefined, - avatarStyle: {}, - textStyle: {}, - } - - static propTypes = { - user: PropTypes.object, - onPress: PropTypes.func, - onLongPress: PropTypes.func, - avatarStyle: StylePropType, - textStyle: StylePropType, - } - - avatarName?: string = undefined - avatarColor?: string = undefined + avatarStyle = {}, + textStyle = {}, + onPress, + } = props - setAvatarColor () { - const userName = (this.props.user && this.props.user.name) || '' + const setAvatarColor = useCallback(() => { + const userName = user.name || '' const name = userName.toUpperCase().split(' ') + if (name.length === 1) - this.avatarName = `${name[0].charAt(0)}` + avatarNameRef.current = `${name[0].charAt(0)}` else if (name.length > 1) - this.avatarName = `${name[0].charAt(0)}${name[1].charAt(0)}` + avatarNameRef.current = `${name[0].charAt(0)}${name[1].charAt(0)}` else - this.avatarName = '' + avatarNameRef.current = '' let sumChars = 0 for (let i = 0; i < userName.length; i += 1) @@ -100,106 +94,108 @@ export default class GiftedAvatar extends React.Component { midnightBlue, ] - this.avatarColor = colors[sumChars % colors.length] - } + avatarColorRef.current = colors[sumChars % colors.length] + }, [user.name]) - renderAvatar () { - const { user } = this.props - if (user) - if (typeof user.avatar === 'function') - return user.avatar([styles.avatarStyle, this.props.avatarStyle]) - else if (typeof user.avatar === 'string') + const renderAvatar = useCallback(() => { + switch (typeof user.avatar) { + case 'function': + return user.avatar([styles.avatarStyle, avatarStyle]) + case 'string': return ( ) - else if (typeof user.avatar === 'number') + case 'number': return ( ) + default: + return null + } + }, [user.name, user.avatar, avatarStyle]) - return null - } - - renderInitials () { + const renderInitials = useCallback(() => { return ( - - {this.avatarName} + + {avatarNameRef.current} ) - } + }, [textStyle]) - handleOnPress = () => { + const handleOnPress = () => { const { - /* eslint-disable @typescript-eslint/no-unused-vars */ onPress, - /* eslint-enable @typescript-eslint/no-unused-vars */ ...rest - } = this.props + } = props - if (this.props.onPress) - this.props.onPress(rest) + if (onPress) + onPress(rest) } - handleOnLongPress = () => { + const handleOnLongPress = () => { const { - /* eslint-disable @typescript-eslint/no-unused-vars */ onLongPress, - /* eslint-enable @typescript-eslint/no-unused-vars */ ...rest - } = this.props + } = props - if (this.props.onLongPress) - this.props.onLongPress(rest) + if (onLongPress) + onLongPress(rest) } - render () { - if (!this.props.user || (!this.props.user.name && !this.props.user.avatar)) - // render placeholder - return ( - - ) - - if (this.props.user.avatar) - return ( - - {this.renderAvatar()} - - ) - - this.setAvatarColor() - + if (!user || (!user.name && !user.avatar)) + // render placeholder return ( - + ) + + if (user.avatar) + return ( + - {this.renderInitials()} + {renderAvatar()} ) - } + + setAvatarColor() + + return ( + + {renderInitials()} + + ) +} + +GiftedAvatar.propTypes = { + user: PropTypes.object, + onPress: PropTypes.func, + onLongPress: PropTypes.func, + avatarStyle: StylePropType, + textStyle: StylePropType, } diff --git a/src/GiftedChat.tsx b/src/GiftedChat.tsx index d7b8ac2ce..f43984da6 100644 --- a/src/GiftedChat.tsx +++ b/src/GiftedChat.tsx @@ -33,7 +33,7 @@ import Bubble from './Bubble' import { Composer, ComposerProps } from './Composer' import { MAX_COMPOSER_HEIGHT, MIN_COMPOSER_HEIGHT, TEST_ID } from './Constant' import { Day, DayProps } from './Day' -import GiftedAvatar from './GiftedAvatar' +import { GiftedAvatar } from './GiftedAvatar' import { GiftedChatContext } from './GiftedChatContext' import { InputToolbar, InputToolbarProps } from './InputToolbar' import { LoadEarlier, LoadEarlierProps } from './LoadEarlier'