Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用promise时,Render不返回任何内容_Javascript_React Native_Promise_Render - Fatal编程技术网

Javascript 使用promise时,Render不返回任何内容

Javascript 使用promise时,Render不返回任何内容,javascript,react-native,promise,render,Javascript,React Native,Promise,Render,我正在尝试实现我的渲染功能,以便它等待我完成从web上抓取数据(如果AsyncStorage没有)或从AsyncStorage中获取数据,但我正在努力实现它的promise方面: render() { let pic = { uri: 'https://i.imgur.com/G19Jnuj.jpg' }; this.renderAttributes() .then((response) => { consol

我正在尝试实现我的渲染功能,以便它等待我完成从web上抓取数据(如果AsyncStorage没有)或从AsyncStorage中获取数据,但我正在努力实现它的promise方面:

render() {
    let pic = {
        uri: 'https://i.imgur.com/G19Jnuj.jpg'
    };
    this.renderAttributes()
        .then((response) => {
            console.log("finished val: " + this.state.name);
            console.log("finished response: " + response);
            return (
                <View style={shared.basicView}>
                    <Image source={pic} style ={styles.circleImage}/>
                    <Text style={styles.infoText}>{this.state.name}</Text>
                    <Text style={styles.titleText}>Bio</Text>
                    <Text style={styles.infoText}>blah blah</Text>
                    <Text style={styles.titleText}>Email</Text>
                    <Text style={styles.infoText}>blah blah</Text>
                    <Text style={styles.titleText}
                          onPress={() => this.props.navigation.navigate('Repositories')}>
                        Public Repos Count</Text>
                    <Text style={styles.infoText}>3</Text>
                    <Text style={styles.titleText}
                          onPress={() => this.props.navigation.navigate('Followers')}>
                        Follower Count</Text>
                    <Text style={styles.infoText}>0</Text>
                    <Text style={styles.titleText}
                          onPress={() => this.props.navigation.navigate('Following')}>
                        Following Count</Text>
                    <Text style={styles.infoText}>0</Text>
                    <Text style={styles.titleText}>Profile Created</Text>
                    <Text style={styles.infoText}>November 2015</Text>
                </View>
            )
        })
        .catch((error) => {
            console.log("Profile creation failed: " + error);
            return(null);
        })
}

(请原谅我所有的console.log语句)。在我看来,无论发生什么情况,这都应该返回null或返回视图,但我一直收到错误
“不变冲突:ProfileScreen(…):渲染时未返回任何内容。这通常意味着缺少return语句。或者,若不渲染任何内容,则返回null。”
。我的catch语句都没有被触发。我真的很困惑;我注意到有两件事可能是罪魁祸首:1。我的IDE突出显示this.state.name作为未解析的变量名,2。我没有在
renderAttributes
中明确定义承诺(我应该这样做吗?)。另外,仅基于print语句,它看起来像是
this.renderAttributes().then(response)
print-before
axios.get.then()
;但我不确定这是不是在转移注意力。有什么建议吗?

这里的问题是,您试图在render()函数中解析一个承诺,而该承诺本身是异步的,并且您不会返回任何隐式返回的内容,因为它将返回未定义的内容

渲染函数应该是纯的,没有任何副作用

您应该将异步逻辑放入react生命周期钩子中的一个钩子中,如
componentWillMount()
componentDidMount()

事实上,最好的地方是组件安装

您应该在第一次运行时提供一个“加载屏幕”(如空字段和/或微调器),当检索到数据(全部在componentDidMount中完成)和状态集时,显示它

组件将安装

避免在这种方法中引入任何副作用或订阅。 对于这些用例,请改用componentDidMount()

组件安装

componentDidMount()在创建组件后立即调用 安装。需要DOM节点的初始化应该在这里进行。如果你 需要从远程端点加载数据,这是一个好地方 实例化网络请求


我不是react用户,但从上次玩它时起,
render
不是一个
async
操作,要处理
async
你会改变
状态,这会导致一个
render
方法,这是从更新视图的状态开始的。@Keith-hmm,我想这就是我所做的。这肯定是一个新手问题,但为什么渲染不是异步的呢?如果我强迫它等待
renderAttributes()
,那还不够吗?
我想这就是我想做的
,只要你使用承诺、异步/等待/回调等,你就可以使用异步。。注:当你等待某件事时,它不会进入同步方法。好的,我阅读了文档,我想确保我理解正确;我应该从
render
中调用
renderAttributes
,然后纯粹返回视图,并将
this.state.
作为元素的值。然后,在
componentDidMount
中,我应该调用
renderAttributes
,这将触发使用更新状态值对呈现进行“重新评估”?确切地说,renderAttributes()中包含的“unpure”逻辑应该放在一个类似于生命周期钩子的componentDidMount()中,当承诺得到解决时,您将设置状态,这将触发重新提交。编辑:看起来调用
componentWillMount
将是一个更好的主意,实际上两者之间有一个很好的比较:
class ProfileScreen extends Component {
    state: any;

    constructor(props) {
        super(props);
        this.state = {
            name: '',
            bio: '',
            email: '',
            repoCount: '',
            followerCount: '',
            followingCount: '',
            profileCreated: ''
        };
        this.renderAttributes = this.renderAttributes.bind(this);
    }

    async renderAttributes() {
        console.log("inside ga");
        let jsonData=null;
        try {
            axios.get('https://api.github.com/users/dummy')
                .then(async (response) => {
                    console.log("Response: " + JSON.stringify(response));
                    jsonData=response;
                    console.log("jsonData: " + JSON.stringify(jsonData));

                    const nameVal = await AsyncStorage.getItem('name');
                    if(nameVal !== null) {
                        console.log("name val: " + nameVal);
                        this.setState({name: nameVal});
                    }
                    else {
                        try {
                            await AsyncStorage.setItem('name', jsonData.data.name);
                        }
                        catch (error) {
                            console.log("Set name error: " + error);
                        }

                        if(jsonData.data.name == null) {
                            this.setState({name: 'n/a'});
                        }
                        else {
                            console.log("name: " + jsonData.data.name);
                            this.setState({name: jsonData.data.name});
                        }
                    }

                    const bio = await AsyncStorage.getItem('bio');
                    if(bio !== null) {
                        this.setState({bio: bio});
                    }
                    else {
                        try {
                            await AsyncStorage.setItem('bio', jsonData.data.bio);
                        }
                        catch (error) {
                            console.log(error);
                        }
                        if(jsonData.data.bio == null) {
                            this.setState({bio: 'n/a'});
                        }
                        else {
                            this.setState({bio: jsonData.data.bio});
                        }
                    }
                    // etc for each attribute in state
                })
                .catch((error) => {
                    console.log('Error fetching: ' + error);
                });

        }
        catch (error) {
            console.log('Error creating attributes: ' + error);
        }
    }