मैं रिएक्ट के साथ एक फिल्टर करने योग्य सूची को लागू करने की प्रक्रिया में हूं। सूची की संरचना नीचे दी गई छवि में दिखाई गई है।
आधार
यहां बताया गया है कि यह कैसे काम करने वाला है:
- राज्य उच्चतम स्तर के घटक, घटक में रहता है
Search। - राज्य का वर्णन इस प्रकार है:
{
दृश्यमान: बूलियन,
फ़ाइलें: सरणी,
फ़िल्टर्ड: सरणी,
क्वेरी स्ट्रिंग,
वर्तमान में चयनितइंडेक्स: पूर्णांक
}
filesएक संभावित रूप से बहुत बड़ा है, फ़ाइल पथ वाले सरणी (10000 प्रविष्टियां एक प्रशंसनीय संख्या है)।filteredउपयोगकर्ता द्वारा कम से कम 2 वर्णों के बाद फ़िल्टर की गई सरणी है। मुझे पता है कि यह व्युत्पन्न डेटा है और राज्य में इसे संग्रहीत करने के बारे में ऐसा तर्क दिया जा सकता है, लेकिन इसके लिए आवश्यक हैcurrentlySelectedIndexफ़िल्टर्ड सूची से वर्तमान में चयनित तत्व का सूचकांक क्या है।Inputघटक में उपयोगकर्ता प्रकार 2 से अधिक अक्षर हैं, सरणी फ़िल्टर की जाती है और फ़िल्टर किए गए सरणी में प्रत्येक प्रविष्टि के लिए एकResultघटक प्रदान किया जाता हैप्रत्येक
Resultघटक पूर्ण पथ प्रदर्शित कर रहा है जो आंशिक रूप से क्वेरी से मेल खाता है, और पथ का आंशिक मिलान भाग हाइलाइट किया गया है। उदाहरण के लिए एक परिणाम घटक के DOM, अगर उपयोगकर्ता टाइप किया था 'le' कुछ इस तरह होगा:<li>this/is/a/fi<strong>le</strong>/path</li>- यदि उपयोगकर्ता अप या डाउन कीज दबाता है जबकि
Inputघटक एरे केcurrentlySelectedIndexआधार पर बदलाव पर केंद्रित हैfiltered। यह उसResultघटक का कारण बनता है जो अनुक्रमणिका से मिलान के रूप में चिह्नित किया जाता है जिससे पुन: रेंडर किया जाता है
मुसीबत
शुरू में मैंने filesरिएक्ट के विकास संस्करण का उपयोग करते हुए एक छोटे से पर्याप्त सरणी के साथ यह परीक्षण किया , और सभी ने ठीक काम किया।
समस्या तब दिखाई दी जब मुझे files10000 प्रविष्टियों के रूप में एक सरणी से निपटना पड़ा । इनपुट में 2 अक्षर टाइप करने से एक बड़ी सूची बन जाएगी और जब मैंने इसे नेविगेट करने के लिए अप और डाउन कीज़ को दबाया तो यह बहुत ही खराब होगा।
पहले मेरे पास Resultतत्वों के लिए एक परिभाषित घटक नहीं था और मैं केवल Searchघटक के प्रत्येक रेंडर पर मक्खी पर सूची बना रहा था , जैसे कि:
results = this.state.filtered.map(function(file, index) {
var start, end, matchIndex, match = this.state.query;
matchIndex = file.indexOf(match);
start = file.slice(0, matchIndex);
end = file.slice(matchIndex + match.length);
return (
<li onClick={this.handleListClick}
data-path={file}
className={(index === this.state.currentlySelected) ? "valid selected" : "valid"}
key={file} >
{start}
<span className="marked">{match}</span>
{end}
</li>
);
}.bind(this));
जैसा कि आप बता सकते हैं, हर बार currentlySelectedIndexबदले जाने पर, यह फिर से रेंडर का कारण बनता है और सूची को हर बार फिर से बनाया जाएगा। मैंने सोचा था कि चूंकि मैंने keyप्रत्येक liतत्व पर एक मूल्य निर्धारित किया था, इसलिए रिएक्ट हर दूसरे liतत्व को फिर से प्रस्तुत करने से बचता है जिसमें इसका classNameपरिवर्तन नहीं था , लेकिन जाहिर है कि ऐसा नहीं था।
मैंने Resultतत्वों के लिए एक वर्ग को परिभाषित करते हुए समाप्त किया , जहां यह स्पष्ट रूप से जांच करता है कि क्या प्रत्येक Resultतत्व को फिर से प्रस्तुत करना चाहिए या नहीं, यह इस आधार पर कि वर्तमान उपयोगकर्ता इनपुट पर आधारित है:
var ResultItem = React.createClass({
shouldComponentUpdate : function(nextProps) {
if (nextProps.match !== this.props.match) {
return true;
} else {
return (nextProps.selected !== this.props.selected);
}
},
render : function() {
return (
<li onClick={this.props.handleListClick}
data-path={this.props.file}
className={
(this.props.selected) ? "valid selected" : "valid"
}
key={this.props.file} >
{this.props.children}
</li>
);
}
});
और सूची अब इस प्रकार बनाई गई है:
results = this.state.filtered.map(function(file, index) {
var start, end, matchIndex, match = this.state.query, selected;
matchIndex = file.indexOf(match);
start = file.slice(0, matchIndex);
end = file.slice(matchIndex + match.length);
selected = (index === this.state.currentlySelected) ? true : false
return (
<ResultItem handleClick={this.handleListClick}
data-path={file}
selected={selected}
key={file}
match={match} >
{start}
<span className="marked">{match}</span>
{end}
</ResultItem>
);
}.bind(this));
}
इससे प्रदर्शन थोड़ा बेहतर हुआ, लेकिन यह अभी भी काफी अच्छा नहीं है। बात यह है कि जब मैंने रिएक्ट चीजों के प्रोडक्शन वर्जन पर परीक्षण किया तो इसमें काफी चिकनी, बिना किसी अंतराल के काम किया।
जमीनी स्तर
प्रतिक्रिया के विकास और उत्पादन संस्करणों के बीच ऐसी ध्यान देने योग्य विसंगति सामान्य है?
क्या मैं समझ रहा हूं / कुछ गलत कर रहा हूं, जब मुझे लगता है कि रिएक्ट सूची को कैसे प्रबंधित करता है?
UPDATE 14-11-2016
मुझे माइकल जैक्सन की यह प्रस्तुति मिली है, जहाँ वह इस मुद्दे को बहुत हद तक इसी तरह से निपटाता है: https://youtu.be/7S8v8jfLb1Q?t=26m2s
समाधान नीचे AskarovBeknar के उत्तर द्वारा प्रस्तावित एक के समान है
अद्यतन 14-4-2018
चूंकि यह स्पष्ट रूप से एक लोकप्रिय सवाल है और मूल प्रश्न पूछे जाने के बाद से चीजें आगे बढ़ी हैं, जबकि मैं आपको ऊपर दिए गए वीडियो को देखने के लिए प्रोत्साहित करता हूं, ताकि एक आभासी लेआउट की समझ प्राप्त कर सके, मैं आपको रिएक्ट वर्चुअलाइज्ड का उपयोग करने के लिए भी प्रोत्साहित करता हूं। पुस्तकालय यदि आप पहिया का फिर से आविष्कार नहीं करना चाहते हैं।



