Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 7c3c04d

Browse files
committed
Fix instances of setState calls after unmount
1 parent e9d56d4 commit 7c3c04d

File tree

4 files changed

+31
-31
lines changed

4 files changed

+31
-31
lines changed

src/components/structures/RoomView.tsx

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,7 @@ export default class RoomView extends React.Component<IProps, IState> {
916916
// called when state.room is first initialised (either at initial load,
917917
// after a successful peek, or after we join the room).
918918
private onRoomLoaded = (room: Room) => {
919+
if (this.unmounted) return;
919920
// Attach a widget store listener only when we get a room
920921
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange);
921922
this.onWidgetLayoutChange(); // provoke an update
@@ -930,9 +931,9 @@ export default class RoomView extends React.Component<IProps, IState> {
930931
};
931932

932933
private async calculateRecommendedVersion(room: Room) {
933-
this.setState({
934-
upgradeRecommendation: await room.getRecommendedVersion(),
935-
});
934+
const upgradeRecommendation = await room.getRecommendedVersion();
935+
if (this.unmounted) return;
936+
this.setState({ upgradeRecommendation });
936937
}
937938

938939
private async loadMembersIfJoined(room: Room) {
@@ -1022,23 +1023,19 @@ export default class RoomView extends React.Component<IProps, IState> {
10221023
};
10231024

10241025
private async updateE2EStatus(room: Room) {
1025-
if (!this.context.isRoomEncrypted(room.roomId)) {
1026-
return;
1027-
}
1028-
if (!this.context.isCryptoEnabled()) {
1029-
// If crypto is not currently enabled, we aren't tracking devices at all,
1030-
// so we don't know what the answer is. Let's error on the safe side and show
1031-
// a warning for this case.
1032-
this.setState({
1033-
e2eStatus: E2EStatus.Warning,
1034-
});
1035-
return;
1026+
if (!this.context.isRoomEncrypted(room.roomId)) return;
1027+
1028+
// If crypto is not currently enabled, we aren't tracking devices at all,
1029+
// so we don't know what the answer is. Let's error on the safe side and show
1030+
// a warning for this case.
1031+
let e2eStatus = E2EStatus.Warning;
1032+
if (this.context.isCryptoEnabled()) {
1033+
/* At this point, the user has encryption on and cross-signing on */
1034+
e2eStatus = await shieldStatusForRoom(this.context, room);
10361035
}
10371036

1038-
/* At this point, the user has encryption on and cross-signing on */
1039-
this.setState({
1040-
e2eStatus: await shieldStatusForRoom(this.context, room),
1041-
});
1037+
if (this.unmounted) return;
1038+
this.setState({ e2eStatus });
10421039
}
10431040

10441041
private onAccountData = (event: MatrixEvent) => {

src/components/structures/TimelinePanel.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
10511051
{ windowLimit: this.props.timelineCap });
10521052

10531053
const onLoaded = () => {
1054+
if (this.unmounted) return;
1055+
10541056
// clear the timeline min-height when
10551057
// (re)loading the timeline
10561058
if (this.messagePanel.current) {
@@ -1092,6 +1094,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
10921094
};
10931095

10941096
const onError = (error) => {
1097+
if (this.unmounted) return;
1098+
10951099
this.setState({ timelineLoading: false });
10961100
console.error(
10971101
`Error loading timeline panel at ${eventId}: ${error}`,

src/components/views/messages/SenderProfile.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ interface IState {
3838
@replaceableComponent("views.messages.SenderProfile")
3939
export default class SenderProfile extends React.Component<IProps, IState> {
4040
static contextType = MatrixClientContext;
41-
private unmounted: boolean;
41+
private unmounted = false;
4242

4343
constructor(props: IProps) {
4444
super(props);
@@ -51,7 +51,6 @@ export default class SenderProfile extends React.Component<IProps, IState> {
5151
}
5252

5353
componentDidMount() {
54-
this.unmounted = false;
5554
this.updateRelatedGroups();
5655

5756
if (this.state.userGroups.length === 0) {
@@ -67,30 +66,24 @@ export default class SenderProfile extends React.Component<IProps, IState> {
6766
}
6867

6968
private async getPublicisedGroups() {
70-
if (!this.unmounted) {
71-
const userGroups = await FlairStore.getPublicisedGroupsCached(
72-
this.context, this.props.mxEvent.getSender(),
73-
);
74-
this.setState({ userGroups });
75-
}
69+
const userGroups = await FlairStore.getPublicisedGroupsCached(this.context, this.props.mxEvent.getSender());
70+
if (this.unmounted) return;
71+
this.setState({ userGroups });
7672
}
7773

7874
private onRoomStateEvents = (event: MatrixEvent) => {
79-
if (event.getType() === 'm.room.related_groups' &&
80-
event.getRoomId() === this.props.mxEvent.getRoomId()
81-
) {
75+
if (event.getType() === 'm.room.related_groups' && event.getRoomId() === this.props.mxEvent.getRoomId()) {
8276
this.updateRelatedGroups();
8377
}
8478
};
8579

8680
private updateRelatedGroups() {
87-
if (this.unmounted) return;
8881
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
8982
if (!room) return;
9083

9184
const relatedGroupsEvent = room.currentState.getStateEvents('m.room.related_groups', '');
9285
this.setState({
93-
relatedGroups: relatedGroupsEvent ? relatedGroupsEvent.getContent().groups || [] : [],
86+
relatedGroups: relatedGroupsEvent?.getContent().groups || [],
9487
});
9588
}
9689

src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
7676
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
7777

7878
private themeTimer: number;
79+
private unmounted = false;
7980

8081
constructor(props: IProps) {
8182
super(props);
@@ -101,6 +102,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
101102
const client = MatrixClientPeg.get();
102103
const userId = client.getUserId();
103104
const profileInfo = await client.getProfileInfo(userId);
105+
if (this.unmounted) return;
104106

105107
this.setState({
106108
userId,
@@ -109,6 +111,10 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
109111
});
110112
}
111113

114+
componentWillUnmount() {
115+
this.unmounted = true;
116+
}
117+
112118
private calculateThemeState(): IThemeState {
113119
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
114120
// show the right values for things.

0 commit comments

Comments
 (0)