React-native-即使调用渲染方法,iOS上的屏幕也不会更新

问题描述 投票:0回答:2

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

创建屏幕后,我必须从API加载一些数据。我用componentDidMountasync方法执行此操作,因此可以使用await关键字。之后,我要设置状态,以便隐藏Loader组件(只是模式显示文本),并使用API​​的数据重新渲染屏幕。在Android设备上运行正常。但是,无法在iOS(iPhone X)上运行此代码。调用SomeScreen.jsLoader.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>
        )
    }
}

ios reactjs react-native render setstate
2个回答
0
投票

我不确定为什么您会看到iOS和Android之间的差异,但是我认为您可以尝试简化Loader组件的渲染方法。这样,您将避免使用2个return调用。

import React, {Component, Fragment} from 'react';

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

上面的代码检查loading属性并加载Modal组件,否则为空。我还将this.props.loading属性作为值添加到模态的visible属性。我认为可能已经丢失了。


0
投票

嗯,终于找到答案了。这是因为即使将animationType设置为none,iOS上的模态上也有打开动画。而且,如果我将loading更改为false,则在捕获此动画之前,仍将打开模态。动画大约需要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毫秒的延迟关闭,因此它有时间完成其弹出动画。

© www.soinside.com 2019 - 2024. All rights reserved.