2015'i Düzenle
Birisi benim çözümümle NPM üzerine bir proje yaptı: https://github.com/lovasoa/react-contenteditable
Düzenleme 06/2016: Tarayıcı az önce verdiğiniz html'yi "yeniden biçimlendirmeye" çalıştığında ortaya çıkan yeni bir sorunu kodladım ve bu da bileşenin her zaman yeniden oluşturulmasına neden oluyor. Görmek
Düzenleme 07/2016: İşte benim üretim içeriğimDüzenlenebilir uygulama. Aşağıdakiler react-contenteditable
dahil olmak üzere isteyebileceğiniz bazı ek seçeneklere sahiptir :
- kilitleme
- html parçalarının yerleştirilmesine izin veren zorunlu API
- içeriği yeniden biçimlendirme yeteneği
Özet:
FakeRainBrigand'ın çözümü, yeni sorunlar alana kadar bir süredir benim için oldukça iyi çalıştı. ContentEditables bir acıdır ve React ile başa çıkmak gerçekten kolay değildir ...
Bu JSFiddle , sorunu göstermektedir.
Gördüğünüz gibi, bazı karakterler yazıp üzerine tıkladığınızda Clear
, içerik temizlenmiyor. Bunun nedeni, içerik düzenlenebilir olanı bilinen son sanal dom değerine sıfırlamaya çalışmamızdır.
Yani öyle görünüyor:
shouldComponentUpdate
Düzeltme pozisyonu atlamalarını önlemeniz gerekir
shouldComponentUpdate
Bu şekilde kullanırsanız React'in VDOM fark algoritmasına güvenemezsiniz .
Dolayısıyla shouldComponentUpdate
, evet döndürdüğünüzde DOM içeriğinin gerçekten güncellendiğinden emin olmanız için fazladan bir satıra ihtiyacınız vardır.
Yani buradaki sürüm a ekler componentDidUpdate
ve şöyle olur:
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;
}
});
Sanal alan güncelliğini yitiriyor ve en verimli kod olmayabilir, ancak en azından çalışıyor :) Hatam çözüldü
Detaylar:
1) İmleç atlamalarını önlemek için shouldComponentUpdate'i koyarsanız, memnun olan asla yeniden oluşturulmaz (en azından tuş vuruşlarında)
2) Bileşen hiçbir zaman tuş vuruşunda yeniden oluşturmazsa, React bu içerik için güncel olmayan bir sanal alan tutar.
3) React, içerik düzenlenebilirliğin güncel olmayan bir sürümünü sanal dom ağacında tutarsa, sanal domainde içerik düzenlenebilirliği güncel olmayan değere sıfırlamaya çalışırsanız, sanal dom farkı sırasında React, üzerinde herhangi bir değişiklik olmadığını hesaplayacaktır. DOM'a başvurun!
Bu çoğunlukla şu durumlarda olur:
- başlangıçta memnun edici boş bir öğeniz var (shouldComponentUpdate = true, prop = "", önceki vdom = N / A),
- kullanıcı bir miktar metin yazar ve siz işlemeleri engellersiniz (shouldComponentUpdate = false, prop = text, önceki vdom = "")
- kullanıcı bir doğrulama düğmesini tıkladıktan sonra, bu alanı boşaltmak istersiniz (shouldComponentUpdate = false, prop = "", önceki vdom = "")
- Hem yeni üretilmiş hem de eski vdom "" olduğundan, React doma dokunmaz.
initialValue
içine koyuyorumstate
ve kullanıyorumrender
, ancak React'in daha fazla güncellemesine izin vermiyorum.