1

The problem is when i click on button to use method changeState, state changes, MoreInfo component shows, but chart is drawing again like this: Actual behavior

Here is my code

import React from 'react'
import './Home.css'
import Graph from '../graph/Graph'
import MoreInfo from '../moreInfo/MoreInfo';

export default class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            showMoreInfo: false
        };
    }

    changeState = () => {
        this.setState({
            showMoreInfo: !this.state.showMoreInfo
        });
    }

    render() {
        return (
            <div className='container'>
                <div className='more_info'>
                    {this.state.showMoreInfo && <MoreInfo />}
                </div>
                <div className='graphs'>
                    <Graph symbol='GOOGL' changeState={this.changeState} />
                </div>
            </div>
        )
    }
}

Code of Graph component

import React from 'react'
import './Graph.css'
import { createChart } from 'lightweight-charts'
import addToObserved from '../../images/addToObserved.svg'

function Graph(props) {
    const myRef = React.useRef();
    React.useEffect(() => {
        getData(props.symbol, 9, myRef);
    });

    return (
        <div className='graph-container'>
            <div ref={myRef} className='graph' />
            <button onClick={props.changeShowMoreInfoState}>More Info</button>
            <div className='addToObserved'>
                <button>
                    <p className='addToObserved-text'>Add to observed</p>
                    <img className='addToObserved-icon'
                        alt='observed_icon'
                        src={addToObserved} />
                </button>
            </div>
        </div>
    );
}

function getData(symbol, months, myRef) {
    let data = [{ time: '2020-10-14', value: 140 }];
    let to = new Date();
    let from = new Date();
    from.setMonth(from.getMonth() - months);
    request(`https://finnhub.io/api/v1/stock/candle` +
        `?symbol=${symbol}` +
        `&resolution=D` +
        `&from=${Math.round(from.getTime() / 1000)}` +
        `&to=${Math.round(to.getTime() / 1000)}` +
        `&token=***`,
        { json: true },
        function (error, response, body) {
            if (error) {
                console.log(error);
                return;
            }
            let date = from;
            body['o'].forEach((element) => {
                date.setDate(date.getDate() + 1);
                data.push({ time: getFormattedDate(date), value: element });
            });
            data.shift();
            makeChart(symbol, data, myRef);
        });
}

function makeChart(title, data, myRef) {
    let width = 550;
    let height = 300;
    let chart = window.tvchart = createChart(myRef.current, {
        width: width,
        height: height,
    });

    let series = chart.addAreaSeries();
    series.setData(data);
}

export default Graph;

I've already checked even without MoreInfo component. If I just change state of parent Component, graph draws one more time. If I click again on button, it draws third time and so more. If I display a lot of charts, all of them draw one more time every button click.

DenBondd
  • 155
  • 1
  • 1
  • 9

1 Answers1

0

As @SureshKumar said, the problem was that I create new chart every time I get data in getData(). I fixed it by passing id to each chart and save it in map like this:

<Graph
    id={1}symbol='GOOGL'
    changeShowMoreInfoState={this.changeShowMoreInfoState} />

and changed my makeChart() method to this:

let listOfCharts = new Map();

function makeChart(id, title, data, myRef) {
    let width = 550;
    let height = 300;
    let chart = listOfCharts.get(id);
    if (chart === undefined) {
        chart = window.tvchart = createChart(myRef.current, {
            width: width,
            height: height,
            grid: {
                horzLines: {
                    visible: false,
                },
            },
        });
    } else {
        return;
    }
    ...
}
DenBondd
  • 155
  • 1
  • 1
  • 9
  • I have the same issue https://stackoverflow.com/questions/67293077/chart-duplicates-because-of-useeffect-re-render – Ibra Apr 29 '21 at 14:10