I am writing a simple reactjs component which updates based off of sockets and api calls. Currently, when a sidebar item is clicked (NavBarSide), the handleNavClick
method is executed. This returns a ticker based off a query handled on the server side. This sets the state to the new ticker. This updates the title bar, but not the graph. From my current understanding of react, this is because the componentWillMount()
method is not called on an update, therefore the new socket connection is not formed.
Should I duplicate the code in the componentWillMount()
function to another lifecycle event? Or write another function which handles the updating of the ticker?
import IO from 'socket.io-client';
import React from "react";
import { BrowserRouter as Router } from "react-router-dom";
import { Dashboard } from "./components/Dashboard";
import { NavBar } from "./components/NavBar";
import { NavBarSide} from "./components/NavBarSide";
import { render } from "react-dom";
import "bootstrap/dist/css/bootstrap.css";
import "../css/index.css";
import 'whatwg-fetch';
let ftse100Tickers = require('./ftse_100_tickers.json');
let randomInt = Math.floor(Math.random() * ftse100Tickers.tickers.length);
class App extends React.Component {
static getTimeSeries(dataSet){
return dataSet.map(row => row.time_stamp)
}
constructor(){
super();
this.state = {
volumeChart: {
labels: [],
datasets: [
{
label: 'Volume',
data: [],
fill: false,
borderColor: "rgb(255, 238, 187)"
},
]
},
status: 'disconnected',
ticker : ftse100Tickers.tickers[randomInt],
twitter : ftse100Tickers.twitter[randomInt]
}
}
componentWillMount(){
this.socket = IO(location.protocol + "//" + document.domain + ":" + location.port);
this.socket.on("connect", (() => this.connect()));
this.socket.on("disconnect", (() => this.disconnect()));
this.socket.on("initial data", ((data) => this.createInitialChart(data)));
}
connect(){
this.setState({status: 'connected'});
this.socket.emit("get initial data", this.state.ticker);
}
disconnect(){
this.setState({status: 'disconnected'})
}
createInitialChart(data) {
const volumeChart = this.state.volumeChart;
const newVolumeChart = {...volumeChart};
newVolumeChart.labels = App.getTimeSeries(data);
newVolumeChart.datasets[0].data = data.map(row => row.volume);
this.setState({ volumeChart: newVolumeChart })
}
handleNavClick(url) {
fetch(url)
.then((response) => response.text())
.then((text) => this.setState({ticker: text}));
}
render() {
return (
<div>
<NavBar/>
<div className="container-fluid">
<div className="row">
<NavBarSide clickHandler={(url) => this.handleNavClick(url)}/>
<Dashboard
volumeChart={this.state.volumeChart}
ticker={this.state.ticker}
twitter={this.state.twitter}
status={this.state.status}
/>
</div>
</div>
</div>
)
}
}
render(<Router><App/></Router>, window.document.getElementById("root"));
2
Answers
try it on
ComponentWillReceiveProps()
If I understand your problem correctly, I think something like this would work :
From React docs :