2016-04-14 26 views
2

Bir tepki bileşeninin içinde üçüncü taraf bir kitaplık kullanarak garip bir hata görüyorum. Bu yazı için gizli bir demo ürettim. Bir grafik kütüphanesi olan ve componentDidMount() bunu render ve this.chart.destroy() doğru çağrıları ile componentWillUnmount() yılında çıkarmadan - React.js işletimi 3. parti kitaplığı yükleme

bana c3js kullanıyorum olduğunu açıklayarak başlayalım.

Hata, bileşenlerin kendileri filtrelendiğinde ortaya çıkar, temel olarak, bileşenler doğru şekilde filtrelenir, ancak bileşenin içinde yer alan gerçek grafik, çok tuhaf bir davranış olan ilk grafikle aynı kalır. Temelde yanlış bileşenin içindeki yanlış grafik!

Sen Remove all charts except chart 3 butonuna tıklayarak ne anlama geldiğini görebilirsiniz, ben chartid ile listelerde etiketlenmiş ve filtreleme doğru diğer çizelgeleri kaldıracaktır.

Filtreleme düzgün çalıştığından ve görünümü güncelleştirdiğinden, kodumun tam olarak belli olmadığından eminim. Doğrulayabilirsiniz, çünkü grafikleri etiketledim ve görünümde görünür. Konsol hatası yok ve kodlarımı doğruladım.

Bu yüzden sorum şu: c3js'yi kullanarak bu sınırlamayı aşabilir miyiz, ya da bu gerçekten benim kodumla ve grafiklerimi oluşturma biçimimle ilgili bir sorundur.

İlgili demo: https://jsfiddle.net/69z2wepo/38614/

İlgili kod:

var data = [ 
    { 
    chartid: 1, 
    columns: [ 
       ['x', 0, 1, 2, 3, 4, 5, 6], 
       ['data1', 130, 300, 330, 400, 300, 400, 500], 
       ['data2', 390, 230, 200, 150, 100, 130, 210], 
       ['data3', 290, 430, 300, 160, 210, 170, 190], 
       ['data4', 190, 330, 200, 260, 190, 250, 320] 
    ] 
    }, 
    { 
    chartid: 2, 
    columns: [ 
       ['x', 0, 1, 2, 3, 4, 5, 6], 
       ['data1', 130, 300, 330, 400, 300, 400, 500], 
       ['data2', 390, 230, 200, 150, 100, 130, 210], 
       ['data3', 290, 430, 300, 160, 210, 170, 190] 
    ] 
    }, 
    { 
    chartid: 3, 
    columns: [ 
       ['x', 0, 1, 2, 3, 4, 5, 6], 
       ['data1', 130, 300, 330, 400, 300, 400, 500], 
       ['data2', 390, 230, 200, 150, 100, 130, 210] 
    ] 
    } 
]; 

var Button = React.createClass({ 
    handleDelete: function (id) { 
    this.props.handleDelete(id); 
    }, 
    render: function() { 
    return (
     <button onClick={this.handleDelete.bind(null, 3)}> 
      Remove all charts except chart 3 
     </button> 
    ) 
    } 
}); 

var Chart = React.createClass({ 
    componentDidMount() { 
    this.chart = c3.generate({ 
     bindto: '.chart-' + this.props.data.chartid, 
     data: { 
      columns: this.props.data.columns 
     } 
    }); 
    }, 
    componentWillUnmount() { 
    this.chart.destroy(); 
    }, 
    render: function() { 
    return (
     <div> 
     <h4>{"chart-" + this.props.data.chartid}</h4> 
     <div className={"chart-" + this.props.data.chartid}> 
     </div> 
     </div> 
    ) 
    } 
}); 

var Child = React.createClass({ 
    renderCharts: function(data) { 
    return data.map(function(metrics, i) { 
     return (
     <Chart key={i} data={metrics} /> 
    ) 
    }); 
    }, 
    handleDelete: function(id) { 
    this.props.handleDelete(id); 
    }, 
    render: function() { 
    return (
     <div> 
     <Button handleDelete={this.handleDelete} /> 
     {this.renderCharts(this.props.data)} 
     </div> 
    ) 
    } 
}) 

var App = React.createClass({ 
    getInitialState: function() { 
    return { 
     initialData: this.props.data 
    } 
    }, 
    handleDelete: function(id) { 
    var _filterFunc = function(data) { 
     if (data.chartid == id) return true; 
     return false; 
    }; 

    var _filterCharts = Array.prototype.filter.call(this.state.initialData, _filterFunc); 

    this.setState({ 
     initialData: _filterCharts 
    }) 
    }, 
    render: function() { 
    return (
     <div> 
     <Child handleDelete={this.handleDelete} data={this.state.initialData} /> 
     </div> 
    ); 
    } 
}); 

ReactDOM.render(
    <App data={data} />, 
    document.getElementById('container') 
); 

cevap

1

sorun grafiğinize anahtarı ayarladığınız yoludur. Oluşturucunun tutmaya çalıştığınız grafik hakkında kafa karıştırmasına neden oluyor.

bu deneyin: <Chart key={data[i].chartid} data={metrics} /> yerine

<Chart key={i} data={metrics} /> arasında nasıl React handles keys bir göz atın. un,'u benzersiz bir şekilde tanımlayan bir çocuğun yaşam döngüsü için bir anahtar ile olduğunu unutmayın. Grafik 1, "1" tuşu ile benzersiz bir şekilde tanımlandığından, "1" tuşu ile grafik 3'ü oluşturamazsınız. Yukarıdaki çözümüm, grafiğin görüntüleme sırası yerine, grafik kimliği ile benzersiz bir şekilde tanımlanmasını sağlar.

+0

Evet haklısınız! Benim atadığım anahtarlar aslında sadece 'harita' döngüsüne dayanıyordu ve aslında grafiklerle alakalı değil, varsayımlar - grafik 3 filtrelenirken 'anahtar = {1}' alıyordu. Bunu açıklamakta mıyım? – AntonB

+1

Tam olarak doğru. Davranış biraz tuhaftır, ancak React'ın yüksek performansa sahip olmasına izin veren optimizasyonları hatırlayın. – TAGraves