【问题标题】:React setState does not set state during a while loopReact setState 在 while 循环期间不设置状态
【发布时间】:2019-07-26 11:37:09
【问题描述】:

我想避免数据乘法,所以我想创建一个循环来为不同的 site_id 调用我的 dataprovider。

我创建了一个 while 循环并在这个 while 循环中设置状态值。我意识到,从我的 2 元素数组(我有 2 个站点)中,只有 1 个被设置为状态,但另一个没有。

class Dashboard extends Component {
state = {
    username: localStorage.getItem('username'),
    siteid: [{
        id: 1,
        daily: "EKdaily",
        weekly: "EKweekly",
        monthly: "EKmonthly",
        total: "EKtotal",
        },
    {
        id: 2,
        daily: "AKdaily",
        weekly: "AKweekly",
        monthly: "AKmonthly",
        total: "AKtotal",
    }]

};

componentDidMount() {
    dataProviderFactory('rest').then(
        dataProvider => {
            dataProvider(GET_ONE, 'users', {
                id: this.state.username,
            })
                .then(response => this.setState({ fullname: response.data.fullname }))

            dataProvider(GET_LIST, 'sites', {
                filter: { q: '' },
                sort: { field: '', order: '' },
                pagination: { page: 1, perPage: 1 },
            })
                .then(response => this.setState({ sites: response.data }))

            var i = 0;
            while ( i < 2 ) {
                var myId = this.state.siteid[i].id;
                var myDaily = this.state.siteid[i].daily;
                var myWeekly = this.state.siteid[i].weekly;
                var myMonthly = this.state.siteid[i].monthly;
                var myTotal = this.state.siteid[i].total;
                console.log("id", myId, myDaily, myWeekly, myMonthly, myTotal);
             dataProvider(GET_LIST, 'clicks', {
                filter: { interval: 'day', site_id: myId, count: '1', },
                sort: { field: 'date', order: 'DESC' },
                pagination: { page: 1, perPage: 50 },
            })
                .then(response => this.setState({ [myDaily]: response.data.count }))
            dataProvider(GET_LIST, 'clicks', {
                filter: { interval: 'week', site_id: myId, count: '1', },
                sort: { field: 'date', order: 'DESC' },
                pagination: { page: 1, perPage: 50 },
            })
                .then(response => this.setState({ [myWeekly]: response.data.count }))
            dataProvider(GET_LIST, 'clicks', {
                filter: { interval: 'month', site_id: myId, count: '1', },
                sort: { field: 'date', order: 'DESC' },
                pagination: { page: 1, perPage: 50 },
            })
                .then(response => this.setState({ [myMonthly]: response.data.count }))
            dataProvider(GET_LIST, 'clicks', {
                filter: { interval: 'all', site_id: myId, count: '1', },
                sort: { field: 'date', order: 'DESC' },
                pagination: { page: 1, perPage: 50 },
            })
                .then(response => this.setState({ [myTotal]: response.data.count }))
                i++;
            }
        }
    );
}

render() {
    const {
        fullname,
        username,
        EKdaily,
        EKweekly,
        EKmonthly,
        EKtotal,
        AKdaily,
        AKweekly,
        AKmonthly,
        AKtotal,
    } = this.state;
    const myPageHeader = `Udvozlunk az Admin feluleten ${fullname}!`;
    return (
        <div style={styles.flex}>
            <div style={styles.leftCol}>
                <div>
                    <Card>
                        <CardHeader title={myPageHeader} />
                        <CardContent>Bejelentkezett felhasznalo: {username}</CardContent>
                    </Card>
                </div>
                <div stlye={ { magrinTop: 200} }>
                    <Typography color="textPrimary">123.hu kattintas statisztikak</Typography>
                </div>
                <div style={styles.flex}>
                    <DisplayClick value={EKdaily} title="Napi Kattintas" />
                    <DisplayClick value={EKweekly} title="Heti Kattintas" />
                    <DisplayClick value={EKmonthly} title="Havi Kattintas" />
                    <DisplayClick value={EKtotal} title="Ossz Kattintas" />
                </div>
                 <div stlye={ { magrinTop: 20} }>
                    <Typography color="textPrimary">345.hu kattintas statisztikak</Typography>
                </div>
                <div style={styles.flex}>
                    <DisplayClick value={AKdaily} title="Napi Kattintas" />
                    <DisplayClick value={AKweekly} title="Heti Kattintas" />
                    <DisplayClick value={AKmonthly} title="Havi Kattintas" />
                    <DisplayClick value={AKtotal} title="Ossz Kattintas" />
                </div>
            </div>
        </div>
   );
}
}

只有 AK* 被设置在 this.state 中,EK* 没有。

我做错了什么?

【问题讨论】:

    标签: javascript reactjs react-native setstate react-admin


    【解决方案1】:

    在这里使用let 而不是var

    改变

    var myId = this.state.siteid[i].id;
    var myDaily = this.state.siteid[i].daily;
    // ....
    

    let myId = this.state.siteid[i].id;
    let myDaily = this.state.siteid[i].daily;
    // ....
    

    var 的作用域是最近的函数,而不是 while 块。它被吊起,您的代码将类似于:

    var i;
    var myId;
    var myDaily;
    
    i = 0;
    
    while ( i < 2 ) {
        myId = this.state.siteid[i].id;
        myDaily = this.state.siteid[i].daily;
    }
    

    由于dataProvider 调用是异步的,所以myId 的值将在第一次调用完成时替换为AK 值。

    dataProvider(GET_LIST, 'clicks', {
        //
    })
     .then(response => this.setState({ [myWeekly]: response.data.count }))
           /* ^^ This callback runs after the while block
               By this time, myDaily === "AKdaily" */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-04
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 2020-10-04
      • 2017-03-30
      • 2020-01-15
      相关资源
      最近更新 更多