Fix TimelinePanel re-renders on duplicate sync state events (#33268)

* Avoid TimelinePanel re-renders on duplicate sync state events

* A better solution avoiding to store the entire syncState
This commit is contained in:
rbondesson
2026-04-24 12:54:01 +00:00
committed by GitHub
parent 76b65b14de
commit 15699c557d
2 changed files with 51 additions and 8 deletions
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
import { render, waitFor, screen, act, cleanup } from "jest-matrix-react";
import {
ClientEvent,
ReceiptType,
EventTimelineSet,
EventType,
@@ -19,6 +20,7 @@ import {
RoomEvent,
RoomMember,
RoomState,
SyncState,
TimelineWindow,
EventTimeline,
FeatureSupport,
@@ -483,6 +485,39 @@ describe("TimelinePanel", () => {
});
});
it("only re-renders when sync changes forward pagination state", async () => {
const [client, room, events] = setupTestData();
let timelinePanel: TimelinePanel | null = null;
render(
<TimelinePanel
{...getProps(room, events)}
ref={(ref) => {
timelinePanel = ref;
}}
/>,
clientAndSDKContextRenderOptions(client, sdkContext),
);
await flushPromises();
await waitFor(() => expect(timelinePanel).toBeTruthy());
const forceUpdateSpy = jest.spyOn(timelinePanel!, "forceUpdate");
await act(async () => {
client.emit(ClientEvent.Sync, SyncState.Syncing, SyncState.Syncing);
await flushPromises();
});
expect(forceUpdateSpy).not.toHaveBeenCalled();
await act(async () => {
client.emit(ClientEvent.Sync, SyncState.Prepared, SyncState.Syncing);
await flushPromises();
});
expect(forceUpdateSpy).toHaveBeenCalledTimes(1);
});
describe("onRoomTimeline", () => {
it("ignores events for other timelines", () => {
const [client, room, events] = setupTestData();