2015-05-14 4 views
5

मुझे यह समझने में परेशानी हो रही है कि Immutable.js कर्सर का उपयोग कर प्रतिक्रिया घटकों के पेड़ के एक शाखा को शॉर्ट सर्किट को कैसे प्रस्तुत किया जाए।Immutable.js कर्सर के साथ React's shouldComponentUpdate का उपयोग

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')); 
}; 

मैं पहली बार Thing के शीर्षक बदलने कहते हैं:

निम्नलिखित उदाहरण लें। केवल Thing के साथ नया शीर्षक और दूसरा Thing shouldComponentUpdate के कारण पुनः प्रस्तुत नहीं करेगा। हालांकि, अगर मैं दूसरे Thing के शीर्षक को बदलता हूं, तो पहले Thing का शीर्षक '' पर वापस जाएगा Thing के कर्सर रूट डेटा के पुराने संस्करण पर इंगित कर रहा है।

हम एक Container की प्रस्तुत करना पर कर्सर लेकिन जो कि shouldComponentUpdate की वजह से नहीं चल करते भी अद्यतन जड़ डेटा के साथ नए कर्सर नहीं मिलता अद्यतन करें। कर्सर को अद्यतित रखने का एकमात्र तरीका यह है कि इस उदाहरण में Thing घटक में shouldComponentUpdate को निकालना है।

क्या इस उदाहरण को shouldComponentUpdate का उपयोग तेजी से संदर्भित समानता जांच का उपयोग करने के लिए करने का कोई तरीका है, लेकिन कर्सर को अद्यतन भी रखें?

या, यदि यह संभव नहीं है, तो क्या आप आम तौर पर कर्सर + प्रतिक्रिया घटक के साथ काम करेंगे और अद्यतन डेटा के साथ केवल घटकों को प्रस्तुत करने के बारे में एक सिंहावलोकन प्रदान कर सकते हैं?

+0

बात मदद करने के लिए एक 'कुंजी' जोड़ने करता है? चीजों की सूची के लिए सही ढंग से काम करने के लिए यह आवश्यक है। – datashaman

+0

चीज अपने राज्य पर होनी चाहिए, और मालिक घटक को उस सूची में मौजूद होना चाहिए या नहीं। आप प्रोप बदल रहे हैं, जो एक बड़ा नो-नो है। – datashaman

+0

मुझे एक ही प्रश्न का सामना करना पड़ रहा है और संकेत किसी प्रकार की एडन लाइब्रेरी का उपयोग करने के लिए इंगित कर रहे हैं जो आपके लिए इसे संभालता है। वर्तमान में, मैं https://omniscientjs.github.io/ पर देख रहा हूं जो वास्तव में आप प्राप्त करने की कोशिश कर रहे हैं। – datashaman

उत्तर

1

मैं अपने कोड अद्यतन, टिप्पणियाँ इनलाइन देखें:

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

हाँ मैं कर्सर को पूरी तरह से ऑब्जेक्ट करने के लिए टिटले चेंज जैसे कुछ लिखने से बचने की उम्मीद कर रहा था लेकिन मैं इसके चारों ओर एक और रास्ता नहीं देख सकता। समय लेने के लिए धन्यवाद, यह तकनीकी रूप से मेरे प्रश्न का सही जवाब है! – franky

संबंधित मुद्दे