response-chartjs-2 не обновляет график при обновлении состояния
Я создаю приложение панели мониторинга, которое извлекает данные из конечной точки и использует метод setState для назначения переменных из JSON, возвращаемых конечной точкой, в переменные состояния. Когда я вношу изменения в состояние, некоторые компоненты, такие как "response-svg-gauge", будут обновляться, но "response-chartjs-2" не обновляется.
Ниже приведен пример того, как мое состояние изменяется в моем фактическом приложении. В этом примере будет отображаться правильное значение переменных состояния в консоли разработчика Chrome, но не обновляется соответственно DOM.
import React, { Component } from 'react';
import {Doughnut} from 'react-chartjs-2';
class DoughnutExample extends Component {
state = {
data: {
labels: [
'Red',
'Green',
'Yellow'
],
datasets: [{
data: [300, 50, 100],
backgroundColor: [
'#FF6384',
'#36A2EB',
'#FFCE56'
],
hoverBackgroundColor: [
'#FF6384',
'#36A2EB',
'#FFCE56'
]
}]
}
}
componentDidMount() {
this.timer = setInterval(
() => this.increment(),
1000
)
}
componentWillUnmount() {
clearInterval(this.timer)
}
increment() {
let datacopy = Object.assign({}, this.state.data)
datacopy.datasets[0].data[0] = datacopy.datasets[0].data[0] + 10
console.log(datacopy.datasets[0].data[0])
this.setState({data: datacopy})
}
render(){
return(
<div>
<Doughnut data = {this.state.data}/>
</div>
)
}
}
export default DoughnutExample;
Я правильно использую методы жизненного цикла? Этот код обновит значение круговой диаграммы, переменную состояния, но не будет правильно отображать DOM.
Ответы
Ответ 1
Потенциальная проблема, которую я вижу, заключается в том, что вы пытаетесь обновить вложенное свойство, пока вы его мутируете. Поэтому, если Doughnut
передает части data
другим компонентам, они не будут уведомлены о том, что реквизит изменился. Поэтому нужно сделать глубокий клон:
increment() {
const datasetsCopy = this.state.data.datasets.slice(0);
const dataCopy = datasetsCopy[0].data.slice(0);
dataCopy[0] = dataCopy[0] + 10;
datasetsCopy[0].data = dataCopy;
this.setState({
data: Object.assign({}, this.state.data, {
datasets: datasetsCopy
})
});
}
Вам также может потребоваться привязать функцию, как предлагает @Janick Fisher.
Ответ 2
Проверьте эту ссылку. Вы можете видеть, что он привязывает функцию к компоненту.
https://codepen.io/gaearon/pen/xEmzGg?editors=0010
// This binding is necessary to make 'this' work in the callback
this.handleClick = this.handleClick.bind(this);
Ответ 3
Вы также можете очистить переменную состояния и заполнить ее снова
как
this.setState({
mainData: {}
});
this.setState({
mainData: md
});
в то время как md
был инициализирован со значением mainData