-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Refactor ParticipantLocalTime to function component #20300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import React, {PureComponent} from 'react'; | ||
| import React, {useState, useEffect} from 'react'; | ||
| import {View} from 'react-native'; | ||
| import lodashGet from 'lodash/get'; | ||
| import styles from '../../../styles/styles'; | ||
|
|
@@ -16,60 +16,52 @@ const propTypes = { | |
| ...withLocalizePropTypes, | ||
| }; | ||
|
|
||
| class ParticipantLocalTime extends PureComponent { | ||
| constructor(props) { | ||
| super(props); | ||
| this.getParticipantLocalTime = this.getParticipantLocalTime.bind(this); | ||
| this.state = { | ||
| localTime: this.getParticipantLocalTime(), | ||
| }; | ||
| function getParticipantLocalTime(participant, preferredLocale) { | ||
| const reportRecipientTimezone = lodashGet(participant, 'timezone', CONST.DEFAULT_TIME_ZONE); | ||
| const reportTimezone = DateUtils.getLocalMomentFromDatetime(preferredLocale, null, reportRecipientTimezone.selected); | ||
| const currentTimezone = DateUtils.getLocalMomentFromDatetime(preferredLocale); | ||
| const reportRecipientDay = reportTimezone.format('dddd'); | ||
| const currentUserDay = currentTimezone.format('dddd'); | ||
|
|
||
| if (reportRecipientDay !== currentUserDay) { | ||
| return `${reportTimezone.format('LT')} ${reportRecipientDay}`; | ||
| } | ||
| return `${reportTimezone.format('LT')}`; | ||
| } | ||
|
|
||
| function ParticipantLocalTime(props) { | ||
| const {participant, preferredLocale, translate} = props; | ||
|
|
||
| componentDidMount() { | ||
| this.timer = Timers.register( | ||
| const [localTime, setLocalTime] = useState(() => getParticipantLocalTime(participant, preferredLocale)); | ||
| useEffect(() => { | ||
| const timer = Timers.register( | ||
| setInterval(() => { | ||
| this.setState({ | ||
| localTime: this.getParticipantLocalTime(), | ||
| }); | ||
| setLocalTime(getParticipantLocalTime(participant, preferredLocale)); | ||
| }, 1000), | ||
| ); | ||
| } | ||
|
|
||
| componentWillUnmount() { | ||
| clearInterval(this.timer); | ||
| } | ||
|
|
||
| getParticipantLocalTime() { | ||
| const reportRecipientTimezone = lodashGet(this.props.participant, 'timezone', CONST.DEFAULT_TIME_ZONE); | ||
| const reportTimezone = DateUtils.getLocalMomentFromDatetime(this.props.preferredLocale, null, reportRecipientTimezone.selected); | ||
| const currentTimezone = DateUtils.getLocalMomentFromDatetime(this.props.preferredLocale); | ||
| const reportRecipientDay = reportTimezone.format('dddd'); | ||
| const currentUserDay = currentTimezone.format('dddd'); | ||
|
|
||
| if (reportRecipientDay !== currentUserDay) { | ||
| return `${reportTimezone.format('LT')} ${reportRecipientDay}`; | ||
| } | ||
| return `${reportTimezone.format('LT')}`; | ||
| } | ||
| return () => { | ||
| clearInterval(timer); | ||
| }; | ||
| }, [participant, preferredLocale]); | ||
|
|
||
| render() { | ||
| const reportRecipientDisplayName = lodashGet(this.props, 'participant.firstName') || lodashGet(this.props, 'participant.displayName'); | ||
| const reportRecipientDisplayName = lodashGet(props, 'participant.firstName') || lodashGet(props, 'participant.displayName'); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @aldo-expensify Shouldn’t we wrap it with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not worth it in my opinion.
Caching
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
hmmm , make sense 👍🏼
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I just understood what you meant here. The interval is updating the state every second. I'll check if setting the state to the same value triggers a re-render or not. If it does, we should only set the state if it is really different.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you , that’s perfect. |
||
|
|
||
| return ( | ||
| <View style={[styles.chatItemComposeSecondaryRow]}> | ||
| <Text | ||
| style={[styles.chatItemComposeSecondaryRowSubText, styles.chatItemComposeSecondaryRowOffset, styles.pre]} | ||
| numberOfLines={1} | ||
| > | ||
| {this.props.translate('reportActionCompose.localTime', { | ||
| user: reportRecipientDisplayName, | ||
| time: this.state.localTime, | ||
| })} | ||
| </Text> | ||
| </View> | ||
| ); | ||
| } | ||
| return ( | ||
| <View style={[styles.chatItemComposeSecondaryRow]}> | ||
| <Text | ||
| style={[styles.chatItemComposeSecondaryRowSubText, styles.chatItemComposeSecondaryRowOffset, styles.pre]} | ||
| numberOfLines={1} | ||
| > | ||
| {translate('reportActionCompose.localTime', { | ||
| user: reportRecipientDisplayName, | ||
| time: localTime, | ||
| })} | ||
| </Text> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| ParticipantLocalTime.propTypes = propTypes; | ||
| ParticipantLocalTime.displayName = 'ParticipantLocalTime'; | ||
|
|
||
| export default withLocalize(ParticipantLocalTime); | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid props destruction as per Style guidelines
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to avoid a warning on the
useEffectwatched values:I think that guideline shouldn't apply well to function components with
useEffectThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we have a similar cases that got resolved with a partial destruction , you can check this thread https://expensify.slack.com/archives/C01GTK53T8Q/p1684969645381109
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting I shouldn't destructure
translatebecause that is not watched and we can keep accessing it asprops.translate?If that is the case, I don't have strong feeling toward that, but I think the best would be to have access to the
translatefunction through a hook like it was suggested here: https://expensify.slack.com/archives/C01GTK53T8Q/p1685068222924839?thread_ts=1684969645.381109&cid=C01GTK53T8QThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry missed this comment. Well,
props.translateshould be watched as well, as the language may change during re-renders.I suggested to proceed with the current destruction of props as you did.