当屏幕第二次安装时,状态未正确更新-React Native

时间:2020-06-14 19:09:14

标签: ios reactjs react-native react-navigation lifecycle

我正在渲染餐厅菜单,并将其显示在ScrollView中。

由于某种原因,我第一次渲染屏幕时,一切工作正常。但是,如果我离开屏幕并再次导航到该屏幕,并且我console.log this.state.catTitlesXValsthis.state.catTitlesWidthsSorted拥有默认状态,这些默认值是在该状态下初始化的。我使用这些功能是为了获得这种效果,您可以在下面的类别中看到:

enter image description here

我不明白为什么第二次导航到屏幕并挂载屏幕时,下面的功能无法正确更新状态。

我真的在这里迷路了,任何帮助将不胜感激。预先谢谢你:)

 componentDidUpdate() {
        // since onLayout for some (weird) reason returns the widths in an unsorted manner,
        // we will sort them since we know that x has to be always in ascending order and
        // we can use that as a reference
        if (this.state.catTitlesXvals.length == this.state.numCategories && !this.state.catTitlesWidthsSorted) {
            this.setState({ catTitlesWidthsSorted: true }, () => {
                var temp = [];
                var xvals = this.state.catTitlesXvals;

                var i;
                for (i = 0; i < this.state.catTitlesXvals.length; i++) {
                    var index;
                    var obj = this.state.catTitlesWidthsRef[i];

                    index = xvals.indexOf(Number(Object.keys(obj)[0]));
                    temp[index] = obj[xvals[index].toString()]
                }
                this.setState({ catTitlesWidths: temp, translateWidth: new Animated.Value(temp[0]) })
            })
        }

    }

    _onLayoutCategories = ({ nativeEvent: { layout: { x, y, width, height } } }) => {
        this.setState(prevState => ({
            categoryYvals: [...prevState.categoryYvals, y].sort(function (a, b) { return a - b })
        }))
    };

    _onLayoutCatTitles = ({ nativeEvent: { layout: { x, y, width, height } } }) => {
        this.setState(prevState => ({
            catTitlesWidths: [...prevState.catTitlesWidths, width],
            catTitlesXvals: [...prevState.catTitlesXvals, x].sort(function (a, b) { return a - b }),
            catTitlesWidthsRef: [...prevState.catTitlesWidthsRef, { [x]: width }]
        }))
    };

    handleScroll = (event) => {
        var y = event.nativeEvent.contentOffset.y

        for (let i = 0; i < this.state.categoryYvals.length; i++) {
            if (y > this.state.categoryYvals[i] && y < this.state.categoryYvals[i + 1]) {
                let translateValueX = this.state.catTitlesXvals[i];
                let translateValueW = this.state.catTitlesWidths[i];
                Animated.parallel([
                    Animated.timing(
                        this.state.translateX,
                        {
                            toValue: translateValueX,
                            duration: 75,
                        }
                    ),
                    Animated.timing(
                        this.state.translateWidth,
                        {
                            toValue: translateValueW,
                            duration: 50,
                        }
                    )
                ]).start()
            }
        }
    }
render() {
        return (
            <View style={styles.container}>
                ...
                <ScrollView stickyHeaderIndices={[0]} ref={(node) => this.scroll = node} onScroll={this.handleScroll} scrollEventThrottle={1}>
                    <View style={{ flex: 1, backgroundColor: 'white', paddingTop: 45 }}>
                        ...

                        <ScrollView style={{ backgroundColor: 'white', borderBottomColor: 'orange', borderBottomWidth: 1 }}
                            horizontal={true}
                            showsHorizontalScrollIndicator={false}
                            ref={(node) => this.scrollTitles = node}>
                            <View style={{ flexDirection: 'row', alignItems: 'center', height: 50 }}>
                                {getCatTitles(this.props.route.params['menu'])}
                            </View>


                            <Animated.View style={[styles.highlight, { left: this.state.translateX, width: this.state.translateWidth }]}></Animated.View>

                        </ScrollView>
                    </View>


                    {DisplayMenu(this.props.route.params['menu'], this)}
                    ...


function DisplayMenu(MenuText, defaultThis) {
    var menu = JSON.parse(MenuText);
    var CategoriesNum;
    CategoriesNum = menu.length;

    var i;
    var components = [];
    for (i = 1; i < CategoriesNum + 1; i++) {
        let catTitle = menu[i - 1][i.toString()]["catTitle"]
        var temp =
            (<View style={styles.category} key={'cat_' + i} onLayout={defaultThis._onLayoutCategories}>
                <Text style={styles.catTitle}>{catTitle}</Text>
                <View style={styles.catItems}>
                    {generateItemC(menu, i, defaultThis)}
                </View>
            </View>);
        components[i] = temp;
    }

    return (
        <View>{components}</View>

    )
}

0 个答案:

没有答案