2015 को संपादित करें
किसी ने मेरे समाधान के साथ एनपीएम पर एक परियोजना बनाई है: https://github.com/lovasoa/react-contentitable
संपादित करें 06/2016: मैंने अभी एक नई समस्या का एनकाउंटर किया है, जब ब्राउज़र उस HTML को " रिफॉर्मेट " करने की कोशिश करता है, जिसे आपने अभी-अभी उसे दिया था, जिसके कारण घटक हमेशा री-रेंडर होता है। देख
07/2016 को संपादित करें: यहां मेरा प्रोडक्शन कंटेंटएडिटेबल इम्प्लीमेंटेशन है । इसके कुछ अतिरिक्त विकल्प हैं react-contenteditable
जो आप चाहते हैं, जिनमें शामिल हैं:
- ताला
- HTML टुकड़े को एम्बेड करने की अनुमति अनिवार्य एपीआई
- सामग्री को पुन: स्वरूपित करने की क्षमता
सारांश:
FakeRainBrigand के समाधान ने कुछ समय तक मेरे लिए काफी ठीक काम किया जब तक कि मुझे नई समस्याएं नहीं मिलीं। ContentEditables एक दर्द है, और वास्तव में React से निपटना आसान नहीं है ...
यह JSFiddle समस्या को प्रदर्शित करता है।
जैसा कि आप देख सकते हैं, जब आप कुछ अक्षर टाइप करते हैं और क्लिक करते हैं Clear
, तो सामग्री साफ़ नहीं होती है। ऐसा इसलिए है क्योंकि हम अंतिम ज्ञात वर्चुअल डोम मूल्य के लिए संतोषप्रद को रीसेट करने का प्रयास करते हैं।
तो ऐसा लगता है कि:
- आपको
shouldComponentUpdate
कैरेट पोजिशन जंप को रोकने की जरूरत है
- यदि आप
shouldComponentUpdate
इस तरह से उपयोग करते हैं तो आप रिएक्ट के VDOM डिफरेंट एल्गोरिथ्म पर भरोसा नहीं कर सकते ।
इसलिए आपको एक अतिरिक्त लाइन की आवश्यकता है ताकि जब भी shouldComponentUpdate
हाँ मिले, तो आपको यकीन है कि DOM सामग्री वास्तव में अपडेट है।
तो यहाँ संस्करण एक componentDidUpdate
और कहते हैं :
var ContentEditable = React.createClass({
render: function(){
return <div id="contenteditable"
onInput={this.emitChange}
onBlur={this.emitChange}
contentEditable
dangerouslySetInnerHTML={{__html: this.props.html}}></div>;
},
shouldComponentUpdate: function(nextProps){
return nextProps.html !== this.getDOMNode().innerHTML;
},
componentDidUpdate: function() {
if ( this.props.html !== this.getDOMNode().innerHTML ) {
this.getDOMNode().innerHTML = this.props.html;
}
},
emitChange: function(){
var html = this.getDOMNode().innerHTML;
if (this.props.onChange && html !== this.lastHtml) {
this.props.onChange({
target: {
value: html
}
});
}
this.lastHtml = html;
}
});
वर्चुअल डोम पुराना हो गया है, और यह सबसे कुशल कोड नहीं हो सकता है, लेकिन कम से कम यह काम करता है :) मेरा बग हल हो गया है
विवरण:
1) यदि आप देखभाल कूद से बचने के लिए shouldComponentUpdate डालते हैं, तो संतोषी कभी रेंडरर्स (कम से कम कीस्ट्रोक्स पर) नहीं करेंगे
2) यदि घटक कभी भी कुंजी स्ट्रोक पर रेंडर नहीं करता है, तो रिएक्ट इस सामग्री के लिए एक पुराना वर्चुअल डोम रखता है।
3) यदि रिएक्ट अपने वर्चुअल डोम ट्री में संतुष्टी का पुराना संस्करण रखता है, तो यदि आप वर्चुअल डोम में पुरानी सामग्री को पुराना करने के लिए सामग्री को रीसेट करने का प्रयास करते हैं, तो वर्चुअल डोम के दौरान, रिएक्ट गणना करेगा कि कोई बदलाव नहीं हैं डोम पर लागू करें!
ऐसा अधिकतर तब होता है जब:
- आपके पास प्रारंभ में एक खाली सामग्री है (shouldComponentUpdate = true, prop = "", पिछला vdom = N / a),
- उपयोगकर्ता कुछ पाठ टाइप करता है और आप रेंडरिंग को रोकते हैं (shouldComponentUpdate = false, prop = text, पिछले vdom) "")
- उपयोगकर्ता द्वारा सत्यापन बटन क्लिक करने के बाद, आप उस फ़ील्ड को खाली करना चाहते हैं (shouldComponentUpdate = false, prop = "", पिछला vdom = "")
- जैसा कि नव निर्मित और पुरानी दोनों कविताएँ "" हैं, रिएक्ट डोम को स्पर्श नहीं करता है।
initialValue
मेंstate
और में इसका इस्तेमाल करते हैंrender
, लेकिन मैं न दें अद्यतन इसे आगे प्रतिक्रिया।