首页 > 解决方案 > 组件挂载前如何获取数据?

问题描述

我的应用程序中有一个屏幕可以加载一些数据。但我认为组件在加载之前就已安装。可能是因为令牌尚未生成。如果不使用超时,我怎么能做到这一点,也许使用反应原生的生命周期方法?ps:当我保存文件2或3次数据加载时,组件为空之前。

我的代码:

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

import Intl from 'intl'
import 'intl/locale-data/jsonp/pt-BR'
import { connect } from 'react-redux'

import { loadPortifolio } from '../../../../store/actions/portifolio'
import CardTitle from '../CardComponents/CardTitle'
import MoneyIcon from '../../../../assets/images/money.svg'
import SavingsIcon from '../../../../assets/images/savings.svg'
import BankIcon from '../../../../assets/images/bank.svg'
import CartIcon from '../../../../assets/images/cart.svg'

import styles from './styles'


class Portifolio extends Component {
    state = {
        list: [],
    }

    componentDidMount = async() => {
        await this.props.onLoadPortifolio()
        this.setState({list: Object.entries(this.props.list).sort()}) //This is the part that I want to load before the component mount.
    }  

    renderListDescription = (description) => {
        let newDescription = ''
        if (description == 'money'){
            return newDescription = 'DINHEIRO'
        } else if (description == 'contacorrente') {
            return newDescription = 'CONTA CORRENTE'
        } else if (description == 'credit') {
            return newDescription = 'CARTÃO DE CRÉDITO'
        } else {
            return newDescription = 'POUPANÇA'
        }
    }

    renderListIcon = (description) => {
        if (description == 'money'){
            return <MoneyIcon width={24} height={24} />
        } else if (description == 'contacorrente') {
            return <BankIcon width={24} height={24} />
        } else if (description == 'credit') {
            return <CartIcon width={24} height={24} />
        } else {
            return <SavingsIcon width={24} height={24} />
        } 
    }

    render(){
        return (
            <View style={styles.container}>
                <CardTitle title='SALDOS CARTEIRAS'/>

                <FlatList
                    data={this.state.list.slice(0, 4)}
                    keyExtractor={(item, index) => item.key}
                    renderItem={({item}) =>

                        <View style={styles.list}>
                            <View style={styles.listIconDescription}>
                                {this.renderListIcon(item[0])}
                                <Text style={styles.descriptionText}>{this.renderListDescription(item[0])}</Text>
                            </View>
                            <Text 
                                style={[item[1] >= 0 ?  {color: '#028FFF'} : 
                                    {color: '#9F261A'}, styles.valueText]}>
                                        {Intl.NumberFormat('pt-BR', 
                                            { style: 'currency', currency: 'BRL' })
                                            .format(item[1])}
                            </Text>
                        </View>
                    }
                />
            </View>
        )
    }
}

const mapStateToProps = ({ portifolio }) => {
    return {
        list: portifolio.list,
        loadError: portifolio.loadError,
    }
}

const mapDispatchToProps = dispatch => {
    return {
        onLoadPortifolio: () => dispatch(loadPortifolio())
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Portifolio)

标签: reactjsreact-nativereact-redux

解决方案


您可以使用生命周期方法

组件WillMount

这是获取数据最合乎逻辑的地方。在组件安装之前获取它,对吗?虽然有一个大但是...

但是有几个问题。

1) 首先,最重要的一点:componentWillMount 从 React 16.3(2018 年 3 月)开始被弃用。

2) 在 componentWillMount 中使用 fetch 或 axios 的 API 调用在第一次渲染之前不会返回。这意味着组件将至少使用空数据呈现一次。

由于 JavaScript 中异步事件的性质,当您启动 API 调用时,浏览器会同时返回执行其他工作。当 React 渲染一个组件时,它不会等待 componentWillMount 完成它开始的任何事情——React 继续前进并继续渲染。

没有办法“暂停”渲染以等待数据到达。您不能以某种方式从 componentWillMount 返回承诺或在 setTimeout 中争吵。处理这个问题的正确方法是设置组件的初始状态,这样即使它在没有数据的情况下呈现,它看起来仍然可以接受。

所以,你可以做什么?您可以呈现一个空列表或显示占位符,或者向新用户显示一些关于如何开始的提示。无论你做什么,都不要尝试遍历未定义的数组,否则你会得到可怕的“无法读取未定义的属性'map'”错误。


推荐阅读