首页 > 解决方案 > React-native - 即使调用渲染方法,iOS 上的屏幕也不会更新

问题描述

我正在开发移动应用程序,但遇到了不知道如何解决的问题。

创建屏幕后,我必须从 API 加载一些数据。我在componentDidMount方法中这样做,async这样我就可以使用await关键字。之后我设置状态,因此 Loader 组件(只是显示文本的模态)被隐藏,屏幕使用来自 API 的数据重新呈现。这在 Android 设备上运行良好。但是在 iOS (iPhone X) 上运行此代码不起作用。SomeScreen.js和的渲染方法Loader.js被调用,Loader.js渲染方法返回 null(用控制台检查)但 iPhone 上的视图没有更新。即使它的渲染方法返回 null,加载器模式仍然存在。我做错什么了吗?打电话this.foceUpdate()也无济于事。

SomeScreen.js

import React, {Component} from 'react';
import Loader from 'components/Loader/Loader';

export default class SomeScreen extends Component {

    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            data: []
        };
    }

    async componentDidMount() {
        const data = await this.loadData();
        this.setState({loading: false, data: data})
    }

    async loadData() {
       //fetch and return data from API
    }

    render() {
        return (
            <SafeAreaView style={{flex: 1}}>
                <Loader loading={this.state.loading}/>
                //other rendering...
            </SafeAreaView>
        );
    }
}

Loader.js

import React, {Component} from 'react';
import {Modal, Text, View} from 'react-native';

export default class Loader extends Component {
    static defaultProps = {
        loading: false
    };

    render() {
        if (this.props.loading !== true) {
           return null;
        }
        return(
          <Modal
              transparent={false}
              animationType={'none'}
              visible={true}>
            <View style={{backgroundColor: "white", flex: 1, justifyContent: "center"}}>
              <Text>Loading data...</Text>
            </View>
          </Modal>
        )
    }
}

标签: iosreactjsreact-nativerendersetstate

解决方案


嗯,终于找到答案了。这是因为即使我设置animationTypenone. 如果我更改loadingfalse,在这个动画被钓到之前,模态仍然是打开的。动画大约需要 550 毫秒,我的 API 调用大约需要 200 毫秒。

Loader.js

import React, {Component} from 'react';
import {Modal, Text, View} from 'react-native';

export default class Loader extends Component {
    static defaultProps = {
        loading: false
    };

    constructor(props) {
        super(props);
        this.state = {
            loading: props.loading
        };
    }

    componentWillReceiveProps(nextProps, nextContext) {
        if (this.state.loading === true && nextProps.loading === false) {
            setTimeout(() => {
                this.setState({loading: false});
            }, 600);
        }
        if (this.state.loading === false && nextProps.loading === true) {
            this.setState({loading: true});
        }
    }

    render() {
        if (this.state.loading !== true) {
           return null;
        }
        return(
          <Modal
              transparent={false}
              animationType={'none'}
              visible={this.state.loading}>
            <View style={{backgroundColor: "white", flex: 1, justifyContent: "center"}}>
              <Text>Loading data...</Text>
            </View>
          </Modal>
        )
    }
}

基本上在我的解决方案中,我确保模态以 600 毫秒的延迟关闭,因此它有时间完成其弹出动画。


推荐阅读