Javascript ReactNative:无法在现有状态转换期间更新(例如在“render”中)。渲染方法应该是道具和状态的纯函数

Javascript ReactNative:无法在现有状态转换期间更新(例如在“render”中)。渲染方法应该是道具和状态的纯函数,javascript,react-native,Javascript,React Native,这是我的代码,我似乎找不到问题。我已经研究了这个问题,但没有找到解决方案,所以我向StackOverflow神寻求帮助 正如你所见,我想在我的加载屏幕中加载字体,并在完成后移动到下一个屏幕。如果有更简单的方法,请告诉我 import React from 'react'; import { StyleSheet, View, AsyncStorage, Alert, ActivityIndicator } from 'react-native'; import { LinearGradient

这是我的代码,我似乎找不到问题。我已经研究了这个问题,但没有找到解决方案,所以我向StackOverflow神寻求帮助

正如你所见,我想在我的加载屏幕中加载字体,并在完成后移动到下一个屏幕。如果有更简单的方法,请告诉我

import React from 'react';
import { StyleSheet, View, AsyncStorage, Alert, ActivityIndicator } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient'
import * as Font from 'expo-font';
import * as firebase from "firebase";


export default class Loading extends React.Component {

constructor(props) {
    super(props);
    this.state = {
        fontLoaded: false,
        client: {
            uid: ""
        }
    };
}


async componentWillMount() {
    //Load fonts + Login to Firebase + capture user ID
    let self = this;
    await Font.loadAsync({
        "Roboto-Regular": require("../assets/fonts/Roboto-Regular.ttf"),
        "Courgette-Regular": require("../assets/fonts/Courgette-Regular.ttf"),
        "Raleway-Regular": require("../assets/fonts/Raleway-Regular.ttf")


    })

    await firebase.auth().signInAnonymously().catch(function (error) {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
        Alert.alert("Error code : " + errorCode, errorMessage)

    });

    //Register the UID
    await this.setState({ uid: firebase.auth().currentUser.uid })

    this.setState({
        client: {
            ...this.state.client,
            uid: firebase.auth().currentUser.uid
        }
    });




    await this.setState({ fontLoaded: true })



}


render() {

    if (this.state.fontLoaded) {

        return (

            this.props.navigation.navigate("Home", { client: this.state.client })
        )
    }

    return (
        <View style={styles.container}>
            <LinearGradient
                colors={["#5B86E5", "#36D1DC"]}
                style={{ flex: 1 }}
            >
                <View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}>

                    <ActivityIndicator size="large" color="#FFF" />

                </View>
            </LinearGradient>
        </View >
    )
}
}

const styles = StyleSheet.create({
    container: {
    flex: 1
}


});
从“React”导入React;
从“react native”导入{样式表、视图、异步存储、警报、ActivityIndicator};
从“expo linear gradient”导入{LinearGradient}
从“expo字体”导入*作为字体;
从“firebase”导入*作为firebase;
导出默认类加载扩展React.Component{
建造师(道具){
超级(道具);
此.state={
错误:,
客户:{
uid:“
}
};
}
异步组件willmount(){
//加载字体+登录Firebase+捕获用户ID
让自我=这个;
等待Font.loadAsync({
“Roboto Regular”:要求(../assets/fonts/Roboto Regular.ttf”),
“常规小胡瓜”:要求(../assets/fonts/Courgette Regular.ttf”),
“Raleway常规”:要求(../assets/fonts/Raleway-Regular.ttf)
})
等待firebase.auth().signinanoymously().catch(函数(错误){
//在这里处理错误。
var errorCode=error.code;
var errorMessage=error.message;
Alert.Alert(“错误代码:”+errorCode,errorMessage)
});
//注册UID
等待此.setState({uid:firebase.auth().currentUser.uid})
这是我的国家({
客户:{
…这个.state.client,
uid:firebase.auth().currentUser.uid
}
});
等待此.setState({fontLoaded:true})
}
render(){
if(this.state.fontload){
返回(
this.props.navigation.navigate(“Home”,{client:this.state.client})
)
}
返回(
)
}
}
const styles=StyleSheet.create({
容器:{
弹性:1
}
});

我认为最好加载
主页
屏幕。执行诸如在页面中提取数据并在操作完成后导航到另一个页面之类的操作是没有效率的。我认为最好在
componentDidMount
生命周期中获取数据,当收到数据时,将
fontload
更改为
true
,如下所示:

import React from 'react';
import { StyleSheet, View, AsyncStorage, Alert, ActivityIndicator } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient'
import * as Font from 'expo-font';
import * as firebase from "firebase";


export default class Home extends React.Component {

constructor(props) {
    super(props);
    this.state = {
        fontLoaded: false,
        client: {
            uid: ""
        }
    };
}


async componentDidMount() {
    //Load fonts + Login to Firebase + capture user ID
    let self = this;
    await Font.loadAsync({
        "Roboto-Regular": require("../assets/fonts/Roboto-Regular.ttf"),
        "Courgette-Regular": require("../assets/fonts/Courgette-Regular.ttf"),
        "Raleway-Regular": require("../assets/fonts/Raleway-Regular.ttf")


    })

    await firebase.auth().signInAnonymously().catch(function (error) {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
        Alert.alert("Error code : " + errorCode, errorMessage)

    });

    //Register the UID
    await this.setState({ uid: firebase.auth().currentUser.uid })

    this.setState({
        client: {
            ...this.state.client,
            uid: firebase.auth().currentUser.uid
        }
    });




    await this.setState({ fontLoaded: true })



}


render() {

    if (this.state.fontLoaded) {

        return (
........... Any code that presents in your Home component

        )
    }

    return (
        <View style={styles.container}>
            <LinearGradient
                colors={["#5B86E5", "#36D1DC"]}
                style={{ flex: 1 }}
            >
                <View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}>

                    <ActivityIndicator size="large" color="#FFF" />

                </View>
            </LinearGradient>
        </View >
    )
}
}

const styles = StyleSheet.create({
    container: {
    flex: 1
}


});
从“React”导入React;
从“react native”导入{样式表、视图、异步存储、警报、ActivityIndicator};
从“expo linear gradient”导入{LinearGradient}
从“expo字体”导入*作为字体;
从“firebase”导入*作为firebase;
导出默认类Home扩展React.Component{
建造师(道具){
超级(道具);
此.state={
错误:,
客户:{
uid:“
}
};
}
异步组件didmount(){
//加载字体+登录Firebase+捕获用户ID
让自我=这个;
等待Font.loadAsync({
“Roboto Regular”:要求(../assets/fonts/Roboto Regular.ttf”),
“常规小胡瓜”:要求(../assets/fonts/Courgette Regular.ttf”),
“Raleway常规”:要求(../assets/fonts/Raleway-Regular.ttf)
})
等待firebase.auth().signinanoymously().catch(函数(错误){
//在这里处理错误。
var errorCode=error.code;
var errorMessage=error.message;
Alert.Alert(“错误代码:”+errorCode,errorMessage)
});
//注册UID
等待此.setState({uid:firebase.auth().currentUser.uid})
这是我的国家({
客户:{
…这个.state.client,
uid:firebase.auth().currentUser.uid
}
});
等待此.setState({fontLoaded:true})
}
render(){
if(this.state.fontload){
返回(
……家庭组件中显示的任何代码
)
}
返回(
)
}
}
const styles=StyleSheet.create({
容器:{
弹性:1
}
});
我希望这对你有帮助。如果这是您想要的解决方案,请投票支持我:)

您正在混合UI(渲染方法)和函数(在渲染内部导航)。当React检测到状态或道具中的更新时,该方法将执行多次

如果这只是一个加载屏幕,则从渲染中删除条件,只显示一个加载屏幕,并从componentDidMount方法导航到下一个屏幕,该方法仅在屏幕加载时触发一次


这将消除错误。基本上,删除setState({fontload:true}),然后从那里导航到下一个屏幕

要在react native应用程序中添加字体,有一个