简体   繁体   中英

React - can't set component's state from props

Quite new to react, I'm facing an unexpected behavior.

I'm trying to visualize data that comes from a database with my react app (ChartJS for the data viz)

This is my App.js (I started from create-react-app ) where I fetch the data from the server's endpoint as a JSON file and I pass it to my BarGraph component:

class App extends Component {
    constructor() {
        super();
        this.state = {
            records_lst : [],
        }
    }

    componentWillMount() {
        this.fetchData();
    }

    fetchData() {
        let data = fetch('http://127.0.0.1:5000/api/dbrecords')
            .then((resp) => {
                resp.json().then((res) => {
                    this.setState({
                        records_lst : res,
                    });
                });
            })
    }

    render() {
        return (<div className="App">
          <BarGraph
              label1={'Toolbox - whole'}
              label2={'tu-ma'}
              textTitle={'Just a Test'}
              times={this.state.records_lst.length}
          />
        </div>);
    }
}

the state records_lst just holds an array of jsons, each of which is one row of the database.

Now, what I'm trying to do is to count how many rows are in the database by counting the length of the records_lst array and send it to the BarGraph component (below) to show one single bar with that value, but for some reason, I can't!

Here is the BarGraph:

class BarGraph extends Component {
constructor(props) {
    super(props);
    this.state = {
        chartData : {
            labels: [this.props.label1],
            datasets: [
                {
                    label: [this.props.label2],
                    data: [this.props.times]
                }
            ]
        }
    }
}

What I noticed is that the props of the component are correct, so "times" is calculated correctly, but the state of the component doesn't pick that number. Screenshot of Chrome's devtools here for clarity

Finally, if in App.js, when I invoke with all the props, I put times={44} (or any other number) the graph shows up normally. I guess for the same reason label : [this.props.label2] works too.

What am I missing here?

Thanks!

use

data: [props.times]

instead of

data: [this.props.times]

and the constructor will get called only once and it is when you load your component for the first time since by then you probably wont have the necessary props with you since you are getting it asynchronously. so better you use it like this.

    componentwillReciveprops(props){
this.setState({data:props.times})
}

@mayak said it correctly above...... the constructor only gets called once

afaik, do not put your props into your state in the constructor.

poll these props inside the render method.

class BarGraph extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        var data = {
            chartData : {
                labels: [this.props.label1],
                datasets: [
                    {
                       label: [this.props.label2],
                       data: [this.props.times]
                    }
                ]
            }
        return (
             <div>hello</div>
        }
    }
}

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