英文:
React Native - Problem with fetch into a component
问题
I understand that you're facing an issue with your React Native application related to fetching and displaying data from a server. It appears that there might be a problem with handling the token data.
Here are some steps you can take to troubleshoot and understand the issue:
-
Make sure you have the necessary dependencies installed and properly configured, such as React Navigation and your context providers.
-
Check if the
token
variable in yourTokenDetail
component is being initialized correctly. It seems to be initially set tonull
, which could lead to the "Cannot read property 'name' of null" error. Ensure thattoken
has a valid value before trying to access its properties. -
Verify that the API request in the
StackTokenDetail
component is returning data as expected. You can add some console logs to check the response and ensure that it contains the necessary information. -
Ensure that the
StackTokenDetail
component is receiving the correctroute.params.id
. Verify that this value is being passed correctly from your list component. -
In the
TokenDetail
component, when displaying the description, make sure thattoken.description
is not null or undefined. You might want to add conditional checks to ensure you're only trying to display the description when it exists. -
Check for any issues with navigation. Ensure that navigating back to the list and selecting a different item works as expected without causing crashes.
-
Consider using try-catch blocks when making API requests to handle potential errors more gracefully and log any errors for debugging purposes.
-
If the issue persists, you can provide more specific error messages or logs to help pinpoint the problem further.
Remember to thoroughly test each component and step in your code to identify where the issue occurs. Debugging and logging can be valuable tools in troubleshooting these kinds of problems.
英文:
I got a problem I can not understand.
I tried to close the App and Expo in Terminal, launch again.
Search on a Google.
I tried many things, but still I got a strange things.
So, I have a list of items (crypto-asset) and when I select one of them, a new window appears with details of this token. Simple.
Here is my "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 }} />}
/>
)
}
My ItemToken (without 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>
)
}
Ok, this it's ok.
Here my component to display the detail of the token.
It's here where I get my problems.
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>
)
}
And my detail stack page:
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)
Well when I start from the list and select an item, I got this error: "Cannot read property 'name' of null.
OK
But, if I delete all lines with the token from JSON in the last component, save and refresh. I select again an item and display the screen. Normal you will say. Right!
But if I put my lines again, save, refresh, then my all console.log will display the informations I get from the server. Everything is here and works. Event the App display the symbol and the name, but not the description (which I got a hours ago).
If I click on the back button, return to the list and select an item (the same one or a different), then crash again...
Please, can you help me to understand?
Also it's why I create a new component for the display the informations and use a memo.
Thank you.
I try to get some data from a server, which doesn't work.
答案1
得分: 1
这个问题是因为在<TokenDetail token={token} />
行危险地传递了token值,尽管它的值为空。在TokenList
组件的开头,您使用const [token, setToken] = useState(null)
来定义状态。也许您可以在这里采取两种方法来解决这个问题。
解决方案1:
在token值不为空之前(通常在您进行的API调用后发生)不显示TokenDetail组件。请参阅下面的代码:
return (
<SafeAreaView>
<ScrollView style={{ flex: 1, padding: 40 }}>
{token ? <TokenDetail token={token} /> : null}
</ScrollView>
</SafeAreaView>
)
解决方案2:
以安全的方式在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>
</>
)
}
英文:
This issue is because you are dangerously passing the token value at <TokenDetail token={token} />
line even though its value is null. At the start of the TokenList
component, you define state using const [token, setToken] = useState(null)
. May be you can do two things here to resolve this issue.
Solution 1:
Do not show the TokenDetail component till the token value is not null(Which eventually happens after the API call you are making. See the code below
return (
<SafeAreaView>
<ScrollView style={{ flex: 1, padding: 40 }}>
{token ? <TokenDetail token={token} /> : null}
</ScrollView>
</SafeAreaView>
)
Solution 2:
Access the token value inside the TokenDetail in a safe manner using the optional chaining technique.
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>
</>
)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论