簡體   English   中英

React.js處理第三方庫安裝

[英]React.js handling 3rd party library mounting

我看到一個在反應組件中使用第三方庫的尷尬錯誤。 我能夠為這篇文章重現一個人為的演示。

首先讓我解釋一下,我正在使用c3js - 這是一個圖表庫並在componentDidMount()呈現它,並使用對this.chart.destroy()的正確調用將其移除到componentWillUnmount() this.chart.destroy()

當過濾組件本身時會發生錯誤,基本上會發生的事情是組件被正確過濾但是組件內部的實際圖表與第一個圖表保持相同,這是非常奇怪的行為。 基本上它是錯誤組件內的錯誤圖表!

你可以看到我通過點擊意味着Remove all charts except chart 3按鈕,我已經標記圖表與chartid和篩選將正確地刪除其他圖表。

我相當肯定這不是我的代碼,因為過濾工作正常並更新了視圖。 您可以驗證,因為我已經標記了圖表,並且它在視圖中可見。 沒有控制台錯誤,我已驗證我的代碼工作。

所以我的問題是 - 我們可以使用c3js來解決這個限制,或者這對我的代碼以及我渲染圖表的方式來說確實是個問題。

相關演示: https//jsfiddle.net/69z2wepo/38614/

相關代碼:

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

問題是您在圖表上設置密鑰的方式。 這導致渲染器對您要保留的圖表感到困惑。

試試這個: <Chart key={data[i].chartid} data={metrics} />而不是<Chart key={i} data={metrics} />

看看React如何處理密鑰 請記住,您使用組件生命周期的鍵來唯一標識孩子。 因此,由於圖表1由鍵“1”唯一標識,因此您無法使用鍵“1”呈現圖表3。 我上面的解決方案確保圖表由其圖表ID唯一標識,而不是由其呈現順序標識。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM