2015-05-14 15 views
5

Immutable.js imleçlerini kullanarak React bileşenlerinin bir dalının bir dalının nasıl kısa devre oluşturulduğunu anlamakta sorun yaşıyorum. React'ın Immutable.js imleçleriyle shouldComponentUpdate'i kullanma

import React from 'react'; 
import Immutable from 'immutable'; 
import Cursor from 'immutable/contrib/cursor'; 

let data = Immutable.fromJS({ 
    things: [ 
    {title: '', key: 1}, 
    {title: '', key: 2} 
    ] 
}); 

class Thing extends React.Component { 
    shouldComponentUpdate(nextProps) { 
    return this.props.thing.deref() !== nextProps.thing.deref(); 
    } 

    handleChangeTitle(e) { 
    this.props.thing.set('title', e.target.value); 
    }  

    render() { 
    return <div> 
     <input value={this.props.thing.get('title')} 
     onChange={this.handleChangeTitle.bind(this)} /> 
    </div>; 
    } 
} 

class Container extends React.Component { 
    render() { 
    const cursor = Cursor.from(this.props.data, 'things', newThings => { 
     data.set('things', newThings); 
     renderContainer(); 
    }); 

    const things = cursor.map(thing => (
     <Thing thing={thing} key={thing.get('key')} /> 
    )); 

    return <div> 
     {things} 
    </div>; 
    } 
} 

const renderContainer =() => { 
    React.render(<Container data={data} />, document.getElementById('someDiv')); 
}; 

İlk Thing 'ın başlığı değiştirmek Say:

aşağıdaki örneğini ele alalım. Yalnızca ilk Thing, yeni başlık ile işlenir ve ikinci Thing, shouldComponentUpdate nedeniyle yeniden oluşturulmaz. Bununla birlikte, ikinci Thing unvanını değiştirirsem, Thing'un ilk Thing unvanı'un başlığına dönecektir, çünkü ikinci Thing imleci hala kök verilerinin eski bir versiyonunu işaret etmektedir.

Her Container render üzerinde imleçler değil, aynı zamanda güncellenmiş kök verileri ile yeni imleç alamadım nedeniyle shouldComponentUpdate render değil yok olanları güncellemek. Imleçleri güncel tutmanın tek yolu bu örnekte shouldComponentUpdate bileşenini Thing bileşeninde kaldırmaktır.

Hızlı başvuru eşitlik denetimleri kullanarak shouldComponentUpdate'u kullanmak için bu örneği değiştirmenin bir yolu var mı, aynı zamanda imleçleri güncel tutuyor mu?

Veya, eğer bu mümkün değilse, genellikle imleçler + React bileşenleri ile nasıl çalışacağınız ve yalnızca güncelleştirilmiş verileri olan bileşenleri nasıl işlediğinize dair bir genel bakış sunabilir misiniz?

Ben kodunuzu updated
+0

Şey çok yardımcı olacak bir 'anahtar' ekleyerek mu? İşlerin doğru bir şekilde çalışabilmesi için gereklidir. – datashaman

+0

Bu şey kendi durumuna dayanmalı ve sahip bileşen o listede bulunup bulunmadığına bakmalıdır. Büyük bir hayır-hayır olan sahne değiştiriyorsun. – datashaman

+0

Aynı sorularla karşı karşıyayım ve işaretler, sizin için bunu işleyen bir tür bir kitaplık kütüphanesini kullanmaya işaret ediyor. Şu anda, tam olarak elde etmeye çalıştığınız şey olan https://omniscientjs.github.io/ adresine bakıyorum. – datashaman

cevap

1

, yorum inline bkz:

class Thing extends React.Component { 
    shouldComponentUpdate(nextProps) { 
    return this.props.thing.deref() !== nextProps.thing.deref(); 
    } 

    handleChangeTitle(e) { 
    // trigger method on Container to handle update 
    this.props.onTitleChange(this.props.thing.get('key'), e.target.value); 
    }  

    render() { 
    return <div> 
     <input value={this.props.thing.get('title')} 
     onChange={this.handleChangeTitle.bind(this)} /> 
    </div>; 
    } 
} 

class Container extends React.Component { 
    constructor() { 
    super(); 
    this.initCursor(); 
    } 

    initCursor() { 
    // store cursor as instance variable to get access from methods 
    this.cursor = Cursor.from(data, 'things', newThings => { 
     data = data.set('things', newThings); 
     // trigger re-render 
     this.forceUpdate(); 
    }); 
    } 

    render() { 
    const things = this.cursor.map(thing => (
     <Thing thing={thing} key={thing.get('key')} onTitleChange={this.onTitleChange.bind(this)} /> 
    )); 

    return <div> 
     {things} 
    </div>; 
    } 

    onTitleChange(key, title){ 
    // update cursor to store changed things 
    this.cursor = this.cursor.update(x => { 
     // update single thing 
     var thing = x.get(key - 1).set('title', title); 
     // return updated things 
     return x.set(key - 1,thing); 
    }); 
    } 
} 

const renderContainer =() => { 
    React.render(<Container data={data} />, document.getElementById('someDiv')); 
}; 
+0

Evet, imlecin dilimlediği tüm nesneyi yönetmek içinTitleChange gibi bir şey yazmaktan kaçınmayı umuyordum ama etrafında başka bir yol göremiyorum. Zaman ayırdığınız için teşekkürler, bu soruya teknik olarak doğru bir cevap! – franky