2016-10-10 32 views
0

Iam试图创建我反应组件的多个实例,但只渲染了第一个实例。我猜iam在这里做了一些重大的失败:)反应组件的多个实例无法正常工作?

这是组件。

import React from 'react'; 
 
import ReactDOM from 'react-dom'; 
 
import ChartJS from 'chart.js' 
 
import DataService from '../core/data-service.js'; 
 

 
function GetReportData() { 
 

 
    let chartElement = document.getElementById('react-chart-bar'); 
 

 
    var id = { 
 
     id: chartElement.dataset.id 
 
    }; 
 

 
    DataService.getReportData(id).done(function(data) { 
 
     renderChart(data); 
 
    }).fail(function(jqXHR, status, error) { 
 
     console.log(error); 
 
    }); 
 
} 
 

 
function renderChart(data) { 
 

 
    var ctx = document.getElementById('chart-bar'); 
 

 
    var chart_bar = new ChartJS(ctx, { 
 
     type: data.ChartType, 
 
     data: { 
 
      labels: data.Labels, 
 
      datasets: data.DataSet 
 
     }, 
 
     options: { 
 
      responsive: true, 
 
      scales: { 
 
       yAxes: [ 
 
        { 
 
         ticks: { 
 
          beginAtZero: true, 
 
          max: data.MaxTicks 
 
         } 
 
        } 
 
       ] 
 
      } 
 
     } 
 
    }); 
 
} 
 

 

 
class Chart extends React.Component { 
 
    componentDidMount() { 
 
     GetReportData(); 
 
    } 
 
    render() { 
 
     return <div> 
 
      <canvas id="chart-bar" width="400" height="300"></canvas> 
 
     </div> 
 
    } 
 
} 
 

 
let node = document.getElementById('react-chart-bar'); 
 

 
if (node != null) { 
 
    ReactDOM.render(
 
     <Chart/>, node); 
 
}

然后在我的HTML我这样调用的组件。

<div id="react-chart-bar" data-id="1"></div> 
 
<div id="react-chart-bar" data-id="9"></div>

我需要呈现相同的组分,而是基于HTML元素上的数据-id属性不同势数据。

感谢您的帮助:)

// g^

+2

没有重复的ID ... – Li357

回答

0

而不是使用id属性,就像你与其他框架,使用ReactDOM.findDOMNode一个阵营组件内部去真正的DOM节点的引用。难道,只有当组件已经呈现,就像里面componentDidMount

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import ChartJS from 'chart.js' 
import DataService from '../core/data-service.js'; 


class Chart extends React.Component { 
    componentDidMount() { 
     let chartElement = ReactDOM.findDOMNode(this); 

     var id = { 
      id: this.props.reportId, 
     }; 

     DataService.getReportData(id).done((data) => { 
      this.renderChart(data); 
     }).fail(function(jqXHR, status, error) { 
      console.log(error); 
     }); 
    } 
    renderChart(data) { 
     var ctx = ReactDOM.findDOMNode(this); 

     var chart_bar = new ChartJS(ctx, { 
      type: data.ChartType, 
      data: { 
       labels: data.Labels, 
       datasets: data.DataSet 
      }, 
      options: { 
       responsive: true, 
       scales: { 
        yAxes: [ 
         { 
          ticks: { 
           beginAtZero: true, 
           max: data.MaxTicks 
          } 
         } 
        ] 
       } 
      } 
     }); 
    } 
    render() { 
     return <div> 
      <canvas width="400" height="300"></canvas> 
     </div> 
    } 
} 

let node = document.getElementById('react-chart-bar'); 

if (node != null) { 
    ReactDOM.render(
     <Chart reportId={node.getAttribute('data-id')} />, 
     node 
    ); 
} 
0

我会建议,其中包装膜成分,使每个ID的图表如下图所示。

function getReportData(id) { 
 
    return `Here is some data for id ${id}`; 
 
} 
 

 
class Chart extends React.Component { 
 
    constructor() { 
 
     super(); 
 
     
 
     this.state = { 
 
     data: null 
 
     }; 
 
    } 
 

 
    componentDidMount() { 
 
     this.setState({ data: getReportData(this.props.dataId) }); 
 
    } 
 
    
 
    render() { 
 
     return (
 
      <div> 
 
      <span>{this.state.data}</span> 
 
      <canvas id="chart-bar" width="400" height="10"></canvas> 
 
      </div> 
 
     );  
 
    } 
 
} 
 

 
class App extends React.Component { 
 
    render() { 
 
     return (
 
      <div> 
 
      <Chart dataId='1' /> 
 
      <Chart dataId='2' /> 
 
      </div> 
 
     ); 
 
    } 
 
} 
 

 
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id='root'></div>