React Native - 渲染从 API 获取数据的屏幕时出现“未定义不是对象”错误
Posted
技术标签:
【中文标题】React Native - 渲染从 API 获取数据的屏幕时出现“未定义不是对象”错误【英文标题】:React Native - "Undefined is not an object" error when render a screen that take data from API 【发布时间】:2021-09-15 22:33:57 【问题描述】:我是 React Native 的新手。我正在制作一个从 API 获取数据并将其显示在屏幕上的应用程序。呈现此屏幕时会出现以下错误: 渲染错误 undefined 不是对象(评估 'character.origin.name')
屏幕上的代码:
const CharacterDetailScreen = (props) =>
const styles, colors = useThemedValues(getStyles);
const loc = useLocalization();
**// state for character detail**
const [character, setCharacter] = useState([])
**// this id come from previous screen**
const characterId = props.route.params
useEffect(()=>
Axios.get('character/'+characterId)
.then(response =>
characterDetail = response.data
setCharacter(characterDetail)
console.log(characterDetail.name) // if characterId=89, writes "dale" in console
)
.catch(error =>
console.log(error)
)
,[])
return (
<View style=styles.container>
<View style=styles.imageContainer>
<Image source= uri: character.image
style=styles.image
/>
</View>
<View style=styles.characterNameContainer>
<Text style=styles.characterName>character.name</Text>
</View>
<View style=styles.detailContainer>
<Text style=styles.detailText >loc.t(texts.status)character.status</Text>
<Text style=styles.detailText >loc.t(texts.species)character.species</Text>
<Text style=styles.detailText >loc.t(texts.gender)character.gender</Text>
<Text style=styles.detailText >loc.t(texts.type)character.type</Text>
<Text style=styles.detailText >loc.t(texts.origin)character.origin.name</Text>
<Text style=styles.detailText >loc.t(texts.location)character.location.name</Text>
</View>
</View>
);
;
export default CharacterDetailScreen;
我检查了来自 API 的传入数据。是不是因为页面渲染的时候数据还没有从api来?
这里是来自 API 的传入数据示例:
const character =
"created": "2017-12-01T10:32:08.340Z",
"episode": ["https://rickandmortyapi.com/api/episode/5"],
"gender": "Male",
"id": 89,
"image": "https://rickandmortyapi.com/api/character/avatar/89.jpeg",
"location": "name": "Giant's Town", "url": "https://rickandmortyapi.com/api/location/14",
"name": "Dale",
"origin": "name": "Giant's Town", "url": "https://rickandmortyapi.com/api/location/14",
"species": "Mythological Creature",
"status": "Dead",
"type": "Giant",
"url": "https://rickandmortyapi.com/api/character/89"
【问题讨论】:
API 网址:rickandmortyapi.com/api 这是因为 setCharacter(characterDetail) 是异步过程,将数据设置为状态需要时间。您面临的错误是因为“字符”状态为空。 你应该在角色有一些数据时加载视图。添加逻辑以仅在数据可用字符时显示视图。 【参考方案1】:解决此问题的简单方法是预先定义您的数据:
const [character, setCharacter] = useState(
"created": "",
"episode": [],
"gender": "",
"id": 0,
"image": undefined,
"location": "name": "", "url": "",
"name": "",
"origin": "name": "", "url": "",
"species": "",
"status": "",
"type": "",
"url": ""
)
这样您就不必再猜测是否定义了字符的属性,并且您不必为可能使用的字符的每个参数添加空检查而头疼。
解决此问题的另一种方法是将默认字符设置为 null 并有条件地呈现用户界面
const CharacterDetailScreen = (props) =>
const styles, colors = useThemedValues(getStyles);
const loc = useLocalization();
**// state for character detail**
const [character, setCharacter] = useState(null])
**// this id come from previous screen**
const characterId = props.route.params
useEffect(()=>
Axios.get('character/'+characterId)
.then(response =>
characterDetail = response.data
setCharacter(characterDetail)
console.log(characterDetail.name) // if characterId=89, writes "dale" in console
)
.catch(error =>
console.log(error)
)
,[])
return (
<View style=styles.container>
character ? (
<View style=styles.imageContainer>
<Image source= uri: character.image style=styles.image/>
</View>
<View style=styles.characterNameContainer>
<Text style=styles.characterName>character.name</Text>
</View>
<View style=styles.detailContainer>
<Text style=styles.detailText >loc.t(texts.status)character.status</Text>
<Text style=styles.detailText >loc.t(texts.species)character.species</Text>
<Text style=styles.detailText >loc.t(texts.gender)character.gender</Text>
<Text style=styles.detailText >loc.t(texts.type)character.type</Text>
<Text style=styles.detailText >loc.t(texts.origin)character.origin.name</Text>
<Text style=styles.detailText >loc.t(texts.location)character.location.name</Text>
</View>
) : (
<Loading/>
)
</View>
);
;
export default CharacterDetailScreen;
【讨论】:
成功了!太感谢了!您对解决“source.uri 不应为空屏”警告有什么建议吗? 是的,使用 undefined 而不是空字符串,或者您可以使用默认图像预先填充它以上是关于React Native - 渲染从 API 获取数据的屏幕时出现“未定义不是对象”错误的主要内容,如果未能解决你的问题,请参考以下文章
React native - 在渲染应用程序组件之前从异步存储中获取数据