简体   繁体   中英

How to save the previous state and current state for a barchart in reactjs

I built a webapp where the user enters some text and we get some scores and create a barchart based on those scores. However I want to create a grouped barchart now for comparison. Suppose the user change something in the text and we get new score so i want to show this new scores in the bar chart with the previous score. It should compare only the current value and the previous value and not go farther than that. I tried to code this but got error like

codesandbox

ReferenceError: Cannot access 'current' before initialization

Editor.js I'm just pasting important parts of the code since it's a big file

import React, { Component, useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Button, Tabs, Tab, Modal } from "react-bootstrap";
import BarChart from "../barCharts";

const style2 = {
  flex: 1,
  textAlign: "center"
};

class MainText extends Component {
  state = {
    analysis: {
      tonal: [],
    },
    showButton: false
  };

Analysis = async () => {
    const { enteredText } = this.state;
    const body = { snippetdesc: enteredText };
    const stringifiedBody = JSON.stringify(body);

    const options = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: stringifiedBody
    };

    const url = `http://localhost:5000/api/apicall`;

    try {
      const response = await fetch(url, options);
      const result = await response.json();


      const {
        ...tonalAnalysis
      } = result.scores;

      const tonalArray = Object.entries(tonalAnalysis).reduce(
        (carry, [tone, value]) => [
          ...carry,
          { tone: tone.toLowerCase(), value: parseInt(value) }
        ],
        []
      );

      this.setState({
        analysis: { ...this.state.analysis, tonal: tonalArray },
        showButton: true
      });

    } catch (error) {
      console.error("error when performing sentiment analysis");
    }
  };

  render() {
    const series = this.state.analysis.tonal.map((tonal) => tonal.value);
    const prev=current;
    const current = series; //error here

    return (
      <div>
        //<textarea>
        //analysis button

        <Button
          className={this.state.showButton ? "showButton" : "hideButton"} //.showButton{visibility: visible}; .hideButton{visibility: hidden}
          onClick={this.showPieModal}
        >
          Show BarChart Modal
        </Button>

        {this.state.showPieModal && (
          <Modal show={this.state.showPieModal} onHide={this.handleClosePie}>
            <Modal.Header closeButton>
              <Modal.Title>Analysis</Modal.Title>
            </Modal.Header>
            <Modal.Body className="pieModal">
              <BarChart data={current} prev={prev}/> 
            </Modal.Body>
            <Modal.Footer>
              <Button variant="secondary" onClick={this.handleClosePie}>
                Close
              </Button>
            </Modal.Footer>
          </Modal>
        )}
      </div>
    );
  }
}

export default MainText;

BarChart.js

import React from "react";
import { Bar } from "react-chartjs-2";
import "./App.css";

class BarChart extends React.Component {
  constructor(props) {
    super(props);
    console.log("props" + JSON.stringify(this.props));
    this.state = {
      data: {
        labels: [
          "January",
          "February",
          "March",

        ],
        datasets: [
          {
            label: "My First dataset",
            backgroundColor: "rgba(255,99,132,0.2)",
            borderColor: "rgba(255,99,132,1)",
            borderWidth: 1,
            //stack: 1,
            hoverBackgroundColor: "rgba(255,99,132,0.4)",
            hoverBorderColor: "rgba(255,99,132,1)",
            data: this.props.data
          },
          {
            label: "My second dataset",
            backgroundColor: "rgba(155,231,91,0.2)",
            borderColor: "rgba(255,99,132,1)",
            borderWidth: 1,
            //stack: 1,
            hoverBackgroundColor: "rgba(255,99,132,0.4)",
            hoverBorderColor: "rgba(255,99,132,1)",
            data: this.props.prev
          }
        ]
      }
    };
  }

  render() {
    const options = {
      responsive: true,
      legend: {
        display: false
      },
      type: "bar",
      scales: {
        yAxes: [{
          ticks: {
            beginAtZero: true
          }
        }]
      }
    };

    return (
      <Bar
        data={this.state.data}
        options={options}
        width={null}
        height={null}
        options={options}
      />

    );
  }
}

export default BarChart;

Error explains it, you are trying to access a constant before you initialize it. const current = series; is after const prev = current; .

But the problem is you are trying to render the previous values without storing them in state. What if your component re-renders? The previous data will be lost.

You want to keep the previous values in state:

state = {
    analysis: {
        tonal: [],
    },
    prevAnalysis: {
        tonal: [],
    },
    showButton: false,
};

Update when you receive new data:

const currAnalysis = // clone this.state.analysis

this.setState({
    prevAnalysis: currAnalysis,
    analysis: { ...this.state.analysis, tonal: tonalArray },
    showButton: true
});

Then use the prevAnalysis in your component as prev. You don't need this

const prev = current;
const current = series;  

Generally, everything that is not saved in state will be used for the current render, whenever you want to keep previous values etc. in memory, you store them in state.

You have error in your code here:

render() {
    const series = this.state.analysis.tonal.map((tonal) => tonal.value);
    const prev=current;
    const current = series; //error here

Your code trying to access value current , and after that you are declaring it using const .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM