繁体   English   中英

react native jsx 在状态更新之前被渲染并抛出未定义的错误

[英]react native jsx is being rendered before state is updated and throwing an undefined error

我有一个正在处理的本地反应项目。 有两个屏幕。 一个屏幕是基于对 zillows api 的 api 调用呈现的属性和详细信息的列表。 单击属性时,我希望它使用传递给新屏幕的 zpid 转到另一个屏幕。

在新屏幕上,我设置了两个状态。 我有一个设置为 true 的加载状态。 在进行新的 api 调用之前,loading 将设置为 true,并且在加载状态设置为 false 之前,我想筛选以呈现加载文本。 一旦加载设置为 false 并且属性状态设置为 api 调用的结果,我想在屏幕上呈现属性详细信息。

我现在的问题是我现在有一个 useEffect,它在屏幕加载时运行 zillow api 调用。 一旦结果存储在属性状态中,我将加载设置为 false。

发生这种情况时,我会遇到一个未定义的变量问题,该问题应该从属性状态呈现属性价格。 我知道这个问题是由于它试图在加载之前从属性状态中抓取而引起的,但我不确定如何延迟渲染内容,直到设置属性状态之后。

零件:

import React, { useState, useEffect } from 'react'
import { Dimensions } from 'react-native'
import { View, Image, Text, StyleSheet, FlatList, TextInput, Button } from 'react-native'
import { ScrollView } from 'react-native-gesture-handler'

import { propertyOptions } from '../api/zillowApi'

import { convertToDollars } from '../utilities'

import axios from 'axios';

const PropertyDetail = (props) => {
  const {
    route
  } = props

  const [property, setProperty] = useState()
  const [loading, setLoading] = useState(true)

  let zpid = route.params.zpid

  let deviceWidth = Dimensions.get('window').width
  var aspectHeight = (deviceWidth / 1.78) + 1
  let carouselImageWidth = (deviceWidth / 4)
  let carouselImageHeight = (carouselImageWidth / 1.78) 

  let options = propertyOptions
  options.params.zpid = zpid
 
  useEffect(() => {
    axios.request(options)
      .then(function (response) {
        // console.log("single property: ", response.data);
        setProperty(response)
        setLoading(false)
      }).catch(function (error) {
        console.error(error);
      });
  }, [])

  const loadingContent = <Text>Loading</Text>

  const loadedContent = <ScrollView>
    <View style={styles.imagesContainer} className="images-container">
      <View style={[styles.mainImageContainer,{height: aspectHeight}]} className="main-image-container">
        <Image style={styles.mainImage} source={{uri: property.data.imgSrc}}/>
      </View>
      <View style={styles.carouselContainer} className="image-carousel-image">
        <FlatList 
          horizontal
          data={carouselImages}
          renderItem={({item}) => <Image style={{height: carouselImageHeight, width:carouselImageWidth}} source={require('../../assets/luxury-home-1.jpeg')}/>}
        />
      </View>
    </View>
    
    ...


        <View style={styles.taxHistoryContainer}>
      <View style={styles.contactContainer}>
        <Text>Listing Agent: Omar Jandali (DRE# 02151051)</Text>
        <Text>Listing Brokerage: Compass (DRE# 00132433)</Text>
      </View>
      <View style={styles.expense}>
        <TextInput placeholder='First Name'/>
        <TextInput placeholder='Last Name'/>
      </View>
      <View style={styles.expense}>
        <TextInput placeholder='Subject'/>
      </View>
      <View style={styles.expense}>
        <TextInput placeholder='Message'/>
      </View>
      <Button title='Submit'/>
      
    </View>
    
  </ScrollView>

  return(
    <View>
      {
        loading == true ? loadingContent : loadedContent
      }
    </View>
  )
}


我想延迟渲染内容,直到我知道属性状态已设置并且我不知道该怎么做...

您可以在 useEffect 和您的组件下方提前返回。

(对不起,如果组件名称不同)。

if (!property) return <LoadingContent />

return (
  <View>
   <LoadedContent />
  </View>
 )

此外,您应该在useState loading设置为 false。 然后在进行axios调用时,将其设置为 true。

const [loading, setLoading] = useState(false);

useEffect(() => {
    setLoading(true);

  try {
    const res = await axios.request(options);
  
    if (res) {
     setProperty(res.data);
    }
  } catch ...
   finally {
    setLoading(false);
  }
  
}, [])

另一方面,您的property状态值的初始值没有什么原因是有原因的吗? 我通常会将其设置为null ,因此如果该状态没有更新,则可以肯定它是错误的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM