React Native -获取组件时出现问题

hivapdat  于 2023-06-24  发布在  React
关注(0)|答案(1)|浏览(119)

我有个问题我不明白。
我试图关闭终端的应用程序和世博会,再次启动。在Google上搜索。我尝试了很多东西,但我仍然得到了一些奇怪的东西。
所以,我有一个项目列表(crypto-asset),当我选择其中一个项目时,会出现一个新窗口,其中包含该令牌的详细信息。很简单
以下是我的“FlatList”:

import { useContext, useEffect, useState } from 'react'
import { Alert, FlatList, View } from 'react-native'
import { SettingsContext } from '../../contexts/SettingsContext'
import ItemToken from '../ItemToken/ItemToken'

export function TokenList() {
  const { currency } = useContext(SettingsContext)
  const [listToken, setListToken] = useState(null)
  const [refreshing, setRefreshing] = useState(false)

  useEffect(() => {
    getListTokens()
  }, [currency])

  useEffect(() => {
    if (refreshing) {
      getListTokens()
      setRefreshing(false)
    }
  }, [refreshing])

  /**
   * For the currency, never mind, it's just Boolean to get things done, it's not the final code.
   */
  function getListTokens() {
    fetch(`https://api.coingecko.com/api/v3/coins/markets?vs_currency=${
      currency ? 'usd' : 'eur'
    }&order=market_cap_desc&per_page=100`)
      .then(response => response.json())
      .then(json => setListToken(json))
      .catch(error => Alert.alert('CoinGecko API Error', error))
    }

return (
  <FlatList
    data={listToken}
    keyExtractor={item => item.id}
    onRefresh={() => setRefreshing(true)}
    refreshing={refreshing}
    renderItem={
      ({ item }) =>
        <ItemToken item={item} />
    }
    ItemSeparatorComponent={<View style={{ height: 1, opacity: 0.6 }} />}
  />
  )
}

我的ItemToken(不含CSS):

import { useContext, memo } from 'react'
import { View, Text, Image, TouchableOpacity, StyleSheet } from 'react-native'
import { SettingsContext } from '../../contexts/SettingsContext'
import { NavigationContext } from '@react-navigation/native'

function ItemToken({ item }) {
  const { currency } = useContext(SettingsContext)
  const { navigation } = useContext(NavigationContext)

  return (
    <TouchableOpacity style={styles.button} onPress={() => navigation.navigate('StackTokenDetail', { id: [item.id] })}>
      <View>
        <Image style={styles.image} src={item.image} />
      </View>
      <View style={styles.mainSection}>
      <Text style={styles.fontStyle}>{item.name}</Text>
      <Text>{currency ? '$' : null}{item.current_price}{currency ? null : '€'}</Text>
      </View>
    </TouchableOpacity>
  )
}

好吧,这没关系。
这里我的组件显示令牌的详细信息。我的问题就出在这里。

import { useEffect, useState } from 'react'
import { SafeAreaView, ScrollView } from 'react-native'
import TokenDetail from '../../TokenDetail/TokenDetail'

export function StackTokenDetail({ route }) {
  const [token, setToken] = useState(null)

  useEffect(() => {
    fetch(`https://api.coingecko.com/api/v3/coins/${route.params.id}`)
      .then(response => response.json())
      .then(json => setToken(json))
      .catch(e => console.error(e))
  }, [])

  return (
    <SafeAreaView>
      <ScrollView style={{ flex: 1, padding: 40 }}>
        <TokenDetail token={token} />
      </ScrollView>
    </SafeAreaView>
  )
}

我的详细堆栈页面:

import { memo } from 'react'
import { Text } from 'react-native'

function TokenDetail({ token }) {
  console.log('tokenDetail token:', token.name)
  console.log('tokenDetail token:', token.symbol.toUpperCase())
  console.log('tokenDetail token:', token.description.en)

  return (
    <>
      <Text style={{ fontWeight: 600, paddingBottom: 20 }}>{token.symbol.toUpperCase()} - {token.name}</Text>
      <Text>{token.description.en}</Text>
    </>
  )
}

export default memo(TokenDetail)

当我从列表开始并选择一个项目时,我得到了这个错误:“无法读取为null的属性'name'。
好的
但是,如果我删除了最后一个组件中JSON中所有带有标记的行,请保存并刷新。我再次选择一个项目并显示屏幕。正常你会说。好的!
但是如果我再次放置我的行,保存,刷新,然后我的all console.log将显示我从服务器获得的信息。一切都在这里和工作。事件应用程序显示符号和名称,但不显示描述(我一个小时前得到的)。
如果我点击后退按钮,返回列表并选择一个项目(相同的或不同的),然后再次崩溃...
拜托,你能帮我弄明白吗?
这也是为什么我创建了一个新的组件显示信息和使用备忘录。
谢谢你。
我试着从服务器上获取一些数据,但不起作用。

bweufnob

bweufnob1#

这个问题是因为您在<TokenDetail token={token} />行传递令牌值,即使它的值为null。在TokenList组件的开头,使用const [token, setToken] = useState(null)定义状态。也许你可以做两件事来解决这个问题。

**解决方案1:**在tokenDetail值不为null之前,不要显示TokenDetail组件(这最终发生在您正在进行的API调用之后)。查看下面的代码

return (
    <SafeAreaView>
      <ScrollView style={{ flex: 1, padding: 40 }}>
        {token ? <TokenDetail token={token} /> : null}
      </ScrollView>
    </SafeAreaView>
)

**方案二:**通过可选的链接技术,安全访问TokenDetail中的token值。

function TokenDetail({ token }) {
  console.log('tokenDetail token:', token?.name)
  console.log('tokenDetail token:', token?.symbol?.toUpperCase())
  console.log('tokenDetail token:', token?.description?.en)

  return (
    <>
      <Text style={{ fontWeight: 600, paddingBottom: 20 }}>{token ? {{token.symbol.toUpperCase()} - {token.name}} : ""}</Text>
      <Text>{token ? token.description.en : ""}</Text>
    </>
  )
}

相关问题