当原始渲染处于活动状态时,React-Native组件不会在setState上重新渲染

时间:2018-04-06 01:23:06

标签: javascript react-native asyncstorage

在我的组件构造函数中,我加载了一个"里程碑列表"和某人戒烟后的天数。里程碑是硬编码的并且同步加载。从AsyncStorage加载天数。我的组件为每个里程碑呈现一个AndroidProgressBar,每个进度条的进度为this.state.days / milestone.duration。在渲染期间,异步返回天数,并使用setState({days})更新状态。更改后的状态不会触发重新渲染,我假设因为它位于原始渲染的中间。这会导致大多数里程碑的进度条不正确。

我已经通过调试器,我可以看到在最后2个里程碑被渲染之前更新了天数,只有它们才正确。

这是我的组成部分。

import React, {Component} from 'react';
import {AppRegistry, StyleSheet, Alert, AsyncStorage} from 'react-native';
import { Container, Header, Content, Body, List, Title} from 'native-base';
import MilestoneItem from '../../components/MilestoneItem/MilestoneItem';

export default class MilestoneScreen extends Component {
    constructor(props) {
        super(props);
        this.state = {
            milestones:[ ],
            days: 0
        };
        /* shape of milestones = [{title: str, duration: number}, ... ] */
        this.state.milestones = this.sortByDuration(props.storageManager.milestones());
        this.getDays();
    }

    async getDays() {
        let settings = await AsyncStorage.getItem("settings");
        settings = JSON.parse(settings);
        this.setState({days: settings.days});
    }

    // Sort the milestones by their duration.
    sortByDuration(array) {
        return array.sort(function(a, b) {
                var x = a.duration;
                var y = b.duration;
                return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });
    }

    render() {
    return (
        <Container>
            <Content>
                <List   dataArray={this.state.milestones}
                        renderRow={ (item) => {
                            let progress = item.duration > this.state.days ?  this.state.days / item.duration  : 1;
                            return <MilestoneItem milestone={item.title} progress={progress} />
                            }
                        }
                />
            </Content>
        </Container>
        );
    }

}

AppRegistry.registerComponent('MilestoneScreen', () => MilestoneScreen);

以下是一些行为的调试器屏幕。此照片显示了渲染功能的开始。 enter image description here

这张照片显示,一旦调用了getDays(),就会成功存储状态。 enter image description here

此照片显示this.state.days已更新,但渲染功能未重启。相反,它只是在它停止的地方继续。

enter image description here

此照片显示的最终结果是每个里程碑都不正确,除了最后的2。

enter image description here

1 个答案:

答案 0 :(得分:0)

React-Native中的List组件在dataArray字段更新时触发重新呈现,而不是在renderRow函数中的任何内容上触发。您必须更新dataArray字段的状态才能触发重新呈现。

易于搜索的标记:列表组件不会重新渲染。