skip to Main Content

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


  1. try it on ComponentWillReceiveProps()

    Login or Signup to reply.
  2. If I understand your problem correctly, I think something like this would work :

    initSocket() {
        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)));
    }
    
    componentWillMount() {
        this.initSocket();
    }
    
    componentWillUpdate(prevState, nextState) {
        if(prevState.ticker !== nextState.ticker)
            this.initSocket();
    }
    

    From React docs :

    componentWillUpdate() is invoked just before rendering when new props or state are being received. Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search