使用RTK Query的Memoized Reselect选择器仍触发组件重渲染
问题:RTK Query轮询时如何避免不稳定属性引发的组件重渲染
我对接的一个API接口中,同一实体每次调用时,返回结果里的unstableProperty属性值会随机变化,示例如下:
// 第一次API调用 GET /entities/3 { "name": "Entity Name", "message": "This is some entity description", "files": [ { "fileName": "File1", "unstableProperty": "bbserg" }, { "fileName": "File2", "unstableProperty": "thslkuygseaf" } ] } // 5秒后第二次API调用 GET /entities/3 { "name": "Entity Name", "message": "This is some entity description", "files": [ { "fileName": "File1", "unstableProperty": "ystgrgazazrg" }, { "fileName": "File2", "unstableProperty": "strhsryjarehaerh" } ] }
业务规则要求每隔X秒轮询该接口以获取数据变更,但我的组件包含一个可能有数百行的表格,每行都有缩略图,每次重渲染会导致性能问题和缩略图闪烁。
我尝试参考RTK Query文档中的selectFromResult示例来避免重渲染,即使设置了过滤不稳定属性的选择器,组件仍会在每次轮询时重渲染。
以下是模拟不稳定属性的API代码:
let calls = 0; export const baseApi = createApi({ baseQuery: fetchBaseQuery(), endpoints: (build) => ({ getTestData: build.query<TestDataResponse, void>({ queryFn: () => ({ data: { name: "Entity Name", message: "This is some entity description", files: [ { fileName: "File1", unstableProperty: `value_${calls++}` }, { fileName: "File2", unstableProperty: `value_${calls++}` }, ], }, }), }), }), });
组件使用该查询的代码如下:
const selectOnlyStableData = useMemo(() => { return createSelector( (data: TestDataResponse | undefined) => data, (data: TestDataResponse | undefined) => { if (!data) return undefined; // 筛选数据中除了files的unstableProperty之外的所有内容 const stableData = { name: data.name, message: data.message, files: data.files.map((f) => ({ fileName: f.fileName, })), }; return stableData; } ); }, []); const { data } = useGetTestDataQuery(undefined, { pollingInterval: 5000, selectFromResult: ({ data }) => ({ data: selectOnlyStableData(data), }), });
尽管使用了选择器,组件仍每5秒重渲染一次。如果完全从查询结果中移除unstableProperty,则一切正常。
请问:如何在使用RTK Query轮询其他数据变更的同时,避免因unstableProperty变化导致的组件重渲染?请注意,我不能直接移除该属性(例如在transformResponse中),因为其他组件需要它的值。
内容的提问来源于stack exchange,提问作者Rychu
相关产品推荐
相关产品推荐

