簡體   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