SectionList unnecessarily unmounts and mounts items when filtering (in between renders)
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- C++
- Star
- 127k
- Fork
- 25.3k
- Merge trung bình
- 1 ngày 23 giờ
- Pull request đã merge (30 ngày)
- 4
Mô tả
Description
When a SectionList rerenders, sometimes it unmounts and remounts some of its items unnecessarily, even though the items preserve the same "key" prop in between renders. This impacts performance.
A scenario where this could happen is when filtering data. Imagine a SectionList with a search bar (TextInput) above it. Every time the user types something in the search bar, the section list gets filtered so it shows the items that contain the text in the search bar. Sometimes, the items get remounted unnecessarily when typing (Why remount an item when it was already there? It passed the filter, it should stay there.)
React Native version:
System:
OS: Windows 10 10.0.18363
CPU: (8) x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
Memory: 6.52 GB / 15.87 GB
Binaries:
Node: 12.14.0 - C:\Program Files\nodejs\node.EXE
Yarn: Not Found
npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
Watchman: Not Found
SDKs:
Android SDK: Not Found
IDEs:
Android Studio: Version 3.6.0.0 AI-192.7142.36.36.6392135
Languages:
Java: Not Found
Python: 2.7.17 - C:\Python27\python.EXE
npmPackages:
@react-native-community/cli: Not Found
react: 16.11.0 => 16.11.0
react-native: 0.62.2 => 0.62.2
npmGlobalPackages:
react-native: Not Found
Steps To Reproduce
- Create a new react-native project.
npx react-native init sectionlisttest - Modify the App.js file so it looks like the following.
import React, {useEffect, useState} from 'react';
import {SectionList, Text, View} from 'react-native';
const originalData = [{
key: 'header1',
header: 'Header 1',
data: [{key: 'firstItem'}, {key: 'byebye1'}],
}];
const filteredData = [{
key: 'header1',
header: 'Header 1',
data: [{key: 'firstItem'}],
}];
export default function App() {
useEffect(() => {
setTimeout(() => setSections(filteredData), 5000);
}, []);
const [sections, setSections] = useState(originalData);
return (
<SectionList
sections={sections}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
ItemSeparatorComponent={Separator}
/>
);
}
const renderItem = ({item}) => <Item item={item} />;
const Item = ({item}) => {
useEffect(() => {
console.log('item mounted');
}, []);
return <Text>{item.key}</Text>;
};
const renderSectionHeader = ({section}) => <Text>{section.header}</Text>;
const Separator = () => <View style={{height: 1, backgroundColor: 'black'}} />;
- Run the app. I ran it in Android (
npx react-native run-android).
IMPORTANT: Fully reload the app, don't depend on hot reloading.
Expected Results
Expected result: 2 lines saying "Item mounted" get printed to the logs.
Actual Result: 2 lines saying "Item mounted" get printed to the logs. . But then, 5 seconds later, it prints a third line also saying "Item mounted".
Snack, code example, screenshot, or link to a repository:
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Tái hiện hành vi từ ví dụ App.js hoặc Snack được liên kết, sử dụng quá trình chuyển đổi dữ liệu của SectionList sau năm giây. Theo dõi những mục nào được mount trong quá trình cập nhật và xem xét hành vi render cũng như cách xử lý key của SectionList. Được xem là hoàn tất khi việc lọc hoặc cập nhật các section không còn mount không cần thiết một mục vẫn giữ cùng key, với một bài kiểm thử hồi quy bao quát kịch bản này.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- javascript, react-native
- Lĩnh vực
- mobile
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 48/100