SectionList unnecessarily unmounts and mounts items when filtering (in between renders)
Personne n'a encore pris cette issue.
- Langage dominant
- C++
- Étoiles
- 127k
- Forks
- 25.3k
- Merge moyen
- 1 j 23 h
- PR mergées (30 j)
- 4
Description
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:
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Reproduisez le comportement de l’exemple App.js ou du Snack lié, en utilisant la transition des données de SectionList après cinq secondes. Suivez les éléments qui sont montés pendant la mise à jour et examinez le comportement de rendu et la gestion des keys de SectionList. C’est terminé lorsque le filtrage ou la mise à jour des sections ne monte plus inutilement un élément qui conserve la même key, avec un test de régression couvrant ce scénario.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript, react-native
- Domaine
- mobile
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 48/100