简体   繁体   中英

React seems to skip for loop

If the question here is a bad one, I apologize in advance. In the following code, I state a simple loop with a loop inside, all within the environment of a React component. For some reason, the test function's callback works, but none of the markers and none of the code inside the loop seems to be executed at all. Is this something to do with asynchronous something? How can I fix it? All advice is appreciated. The code that is of concern is the function labeled "test" and the execution of the function resides in the "render" function.

import React, {Component} from 'react';
import {Line} from 'react-chartjs-2';
import axios from 'axios';

var gData;
var a;
var dateArray = [];
class Graph extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            resolution: 'year',
            range: 7,
            data: this.props.data,
            dataLen: this.props.data.length,
            rendered: false,
            dataDisp: null,
        }
    }
    setGraph=()=>{
        switch (this.state.resolution) {
            case 'year':
                var dateArray = [];
                for(var i = 0; this.state.data.length;i++){
                    var yearTotal;
                    var yearA = this.state.data[i].date.substr(0,3);
                    yearTotal = this.state.data[i].time;
                    for(var j=0; this.state.data.length;j++){
                        var yearB = this.state.data[j].date.substr(0,3);
                        if((yearA === yearB) && (i != j)){
                            yearTotal += this.state.data[j].time;
                        }
                    }
                    var yearArray = [yearA, yearTotal];
                    dateArray.push(yearArray);
                }
            break;
            console.log(dateArray);
        }
    }
    test=(callback)=>{
        for(var i=0; j < this.state.data.length;i++){
            console.log(i);
            var yearTotal;
            var yearA = this.state.data[i].date.substr(0,4);
            yearTotal = parseInt(this.state.data[i].time);

            for(var j=0; j < this.state.data.length;j++){
                var yearB = this.state.data[j].date.substr(0,4);
                if((yearA === yearB) && (i != j)){
                    yearTotal += this.state.data[j].time;
                }
                console.log("Marker, which doesn't show up");
            }
            var yearArray = [yearA, yearTotal];

            dateArray.push(yearArray);
            if(i === (this.state.data.length-1)){
                callback();
            }
        }
    }
    render(){
        gData = {
            labels: [],
            datasets: [
                {
                    label: 'My First dataset',
                    fill: true,
                    lineTension: 0.1,
                    backgroundColor: 'rgba(75,192,192,0.4)',
                    borderColor: 'rgba(75,192,192,1)',
                    borderCapStyle: 'butt',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'miter',
                    pointBorderColor: 'rgba(75,192,192,1)',
                    pointBackgroundColor: '#fff',
                    pointBorderWidth: 1,
                    pointHoverRadius: 5,
                    pointHoverBackgroundColor: 'rgba(75,192,192,1)',
                    pointHoverBorderColor: 'rgba(220,220,220,1)',
                    pointHoverBorderWidth: 2,
                    pointRadius: 1,
                    pointHitRadius: 10,
                    data: this.state.data
                }
            ]
        };

        this.test(console.log(dateArray));

            return(
            <div>
                <div id="resolution">
                    <h2>Resolution</h2>
                    <select>
                    <option value="day">Days</option>
                    <option value="week">Weeks</option>
                    <option value="month">Months</option>
                    <option value="year">Years</option>
                    </select>
                </div>
                <Line data={gData}/>
            </div>

            );


    }
}
export default Graph

It's more of React lifecycle thing; in the first call for the render method by react's internals, you execute the "test" function and make changes for on the "dateArray", however after the changes are made in order for the UI to be updated, the render method needs to be called again. How to do that ? react automatically re-renders the component whenever the state changes, so try to put any UI related variables in the state.

What to do ? move the dateArray to the component's state, use "this.setState" function to patch any updates to it.

There's a good article talking more about setState https://medium.com/@baphemot/understanding-reactjs-setstate-a4640451865b you can check it out

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