Fix instances of setState calls after unmount
parent
e9d56d4f13
commit
7c3c04d340
|
@ -916,6 +916,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
// called when state.room is first initialised (either at initial load,
|
// called when state.room is first initialised (either at initial load,
|
||||||
// after a successful peek, or after we join the room).
|
// after a successful peek, or after we join the room).
|
||||||
private onRoomLoaded = (room: Room) => {
|
private onRoomLoaded = (room: Room) => {
|
||||||
|
if (this.unmounted) return;
|
||||||
// Attach a widget store listener only when we get a room
|
// Attach a widget store listener only when we get a room
|
||||||
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange);
|
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange);
|
||||||
this.onWidgetLayoutChange(); // provoke an update
|
this.onWidgetLayoutChange(); // provoke an update
|
||||||
|
@ -930,9 +931,9 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private async calculateRecommendedVersion(room: Room) {
|
private async calculateRecommendedVersion(room: Room) {
|
||||||
this.setState({
|
const upgradeRecommendation = await room.getRecommendedVersion();
|
||||||
upgradeRecommendation: await room.getRecommendedVersion(),
|
if (this.unmounted) return;
|
||||||
});
|
this.setState({ upgradeRecommendation });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadMembersIfJoined(room: Room) {
|
private async loadMembersIfJoined(room: Room) {
|
||||||
|
@ -1022,23 +1023,19 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private async updateE2EStatus(room: Room) {
|
private async updateE2EStatus(room: Room) {
|
||||||
if (!this.context.isRoomEncrypted(room.roomId)) {
|
if (!this.context.isRoomEncrypted(room.roomId)) return;
|
||||||
return;
|
|
||||||
}
|
// If crypto is not currently enabled, we aren't tracking devices at all,
|
||||||
if (!this.context.isCryptoEnabled()) {
|
// so we don't know what the answer is. Let's error on the safe side and show
|
||||||
// If crypto is not currently enabled, we aren't tracking devices at all,
|
// a warning for this case.
|
||||||
// so we don't know what the answer is. Let's error on the safe side and show
|
let e2eStatus = E2EStatus.Warning;
|
||||||
// a warning for this case.
|
if (this.context.isCryptoEnabled()) {
|
||||||
this.setState({
|
/* At this point, the user has encryption on and cross-signing on */
|
||||||
e2eStatus: E2EStatus.Warning,
|
e2eStatus = await shieldStatusForRoom(this.context, room);
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this point, the user has encryption on and cross-signing on */
|
if (this.unmounted) return;
|
||||||
this.setState({
|
this.setState({ e2eStatus });
|
||||||
e2eStatus: await shieldStatusForRoom(this.context, room),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAccountData = (event: MatrixEvent) => {
|
private onAccountData = (event: MatrixEvent) => {
|
||||||
|
|
|
@ -1051,6 +1051,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
{ windowLimit: this.props.timelineCap });
|
{ windowLimit: this.props.timelineCap });
|
||||||
|
|
||||||
const onLoaded = () => {
|
const onLoaded = () => {
|
||||||
|
if (this.unmounted) return;
|
||||||
|
|
||||||
// clear the timeline min-height when
|
// clear the timeline min-height when
|
||||||
// (re)loading the timeline
|
// (re)loading the timeline
|
||||||
if (this.messagePanel.current) {
|
if (this.messagePanel.current) {
|
||||||
|
@ -1092,6 +1094,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onError = (error) => {
|
const onError = (error) => {
|
||||||
|
if (this.unmounted) return;
|
||||||
|
|
||||||
this.setState({ timelineLoading: false });
|
this.setState({ timelineLoading: false });
|
||||||
console.error(
|
console.error(
|
||||||
`Error loading timeline panel at ${eventId}: ${error}`,
|
`Error loading timeline panel at ${eventId}: ${error}`,
|
||||||
|
|
|
@ -38,7 +38,7 @@ interface IState {
|
||||||
@replaceableComponent("views.messages.SenderProfile")
|
@replaceableComponent("views.messages.SenderProfile")
|
||||||
export default class SenderProfile extends React.Component<IProps, IState> {
|
export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
static contextType = MatrixClientContext;
|
static contextType = MatrixClientContext;
|
||||||
private unmounted: boolean;
|
private unmounted = false;
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -51,7 +51,6 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.unmounted = false;
|
|
||||||
this.updateRelatedGroups();
|
this.updateRelatedGroups();
|
||||||
|
|
||||||
if (this.state.userGroups.length === 0) {
|
if (this.state.userGroups.length === 0) {
|
||||||
|
@ -67,30 +66,24 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getPublicisedGroups() {
|
private async getPublicisedGroups() {
|
||||||
if (!this.unmounted) {
|
const userGroups = await FlairStore.getPublicisedGroupsCached(this.context, this.props.mxEvent.getSender());
|
||||||
const userGroups = await FlairStore.getPublicisedGroupsCached(
|
if (this.unmounted) return;
|
||||||
this.context, this.props.mxEvent.getSender(),
|
this.setState({ userGroups });
|
||||||
);
|
|
||||||
this.setState({ userGroups });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRoomStateEvents = (event: MatrixEvent) => {
|
private onRoomStateEvents = (event: MatrixEvent) => {
|
||||||
if (event.getType() === 'm.room.related_groups' &&
|
if (event.getType() === 'm.room.related_groups' && event.getRoomId() === this.props.mxEvent.getRoomId()) {
|
||||||
event.getRoomId() === this.props.mxEvent.getRoomId()
|
|
||||||
) {
|
|
||||||
this.updateRelatedGroups();
|
this.updateRelatedGroups();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private updateRelatedGroups() {
|
private updateRelatedGroups() {
|
||||||
if (this.unmounted) return;
|
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
|
|
||||||
const relatedGroupsEvent = room.currentState.getStateEvents('m.room.related_groups', '');
|
const relatedGroupsEvent = room.currentState.getStateEvents('m.room.related_groups', '');
|
||||||
this.setState({
|
this.setState({
|
||||||
relatedGroups: relatedGroupsEvent ? relatedGroupsEvent.getContent().groups || [] : [],
|
relatedGroups: relatedGroupsEvent?.getContent().groups || [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
|
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
|
||||||
|
|
||||||
private themeTimer: number;
|
private themeTimer: number;
|
||||||
|
private unmounted = false;
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -101,6 +102,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const userId = client.getUserId();
|
const userId = client.getUserId();
|
||||||
const profileInfo = await client.getProfileInfo(userId);
|
const profileInfo = await client.getProfileInfo(userId);
|
||||||
|
if (this.unmounted) return;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
userId,
|
userId,
|
||||||
|
@ -109,6 +111,10 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unmounted = true;
|
||||||
|
}
|
||||||
|
|
||||||
private calculateThemeState(): IThemeState {
|
private calculateThemeState(): IThemeState {
|
||||||
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
|
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
|
||||||
// show the right values for things.
|
// show the right values for things.
|
||||||
|
|
Loading…
Reference in New Issue