提问者:小点点

即使调用render方法,iOS上的react-native-screen也不会更新


我正在做移动应用程序,我遇到了一些问题,我不知道如何解决。

我必须在创建一个屏幕后从API加载一些数据。 我在ComponentDidMount方法中执行此操作,该方法是Async,因此我可以使用Await关键字。 然后,我设置状态,这样加载器组件(它只是模态显示文本)就会被隐藏,屏幕会用来自API的数据重新呈现。 这在Android设备上运行良好。 但是在iOS(iPhone X)上运行这段代码是行不通的。 调用somescreen.jsloader.js的呈现方法,并且loader.js呈现方法返回null(与控制台检查),但iPhone上的视图没有更新。 加载器模式仍然存在,即使它的render方法返回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>
        )
    }
}


共2个答案

匿名用户

我不知道为什么您会看到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道具中。 我想那个可能已经不见了。

匿名用户

我终于找到答案了。 这是因为即使我将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>
        )
    }
}

基本上,在我的解决方案中,我确保modal以600毫秒的延迟关闭,这样它就有时间完成它的弹出动画。