React Native开发Hacker News克隆项目时遭遇Cannot read property of undefined(reading 'map')错误求助
Let's walk through exactly what's going wrong and how to fix it step by step:
1. The Immediate Error Cause
You're trying to call this.state.newdata.map() in your render method, but newdata doesn't exist in your component's state—you defined data instead. That's why you're hitting the "undefined" error right out the gate.
Even if you fixed that to use this.state.data, you'd still run into issues because of how you're handling the API response.
2. API Response Mismatch
The API endpoint you're calling (https://hacker-news.firebaseio.com/v0/item/26061935.json) returns a single Hacker News story object, not an array wrapped in a data field. When you set data: json.data, you're assigning undefined to your state's data (since the response has no data property at all).
Option A: Display a Single Story
If you want to show just that one specific story, update your code like this:
import React from 'react'; import { Card, Text } from "react-native-paper"; import { SafeAreaView, } from "react-native"; class Hnews extends React.Component { constructor(props) { super(props); this.state = { data: null, // Use null instead of array for single object isLoaded: false, }; } async componentDidMount() { // Use async/await consistently instead of mixing with .then() try { const res = await fetch("https://hacker-news.firebaseio.com/v0/item/26061935.json?print=pretty"); const json = await res.json(); this.setState({ isLoaded: true, data: json, // Assign the whole story object directly }); } catch (err) { console.error("Error fetching data:", err); } } render() { const { isLoaded, data } = this.state; // Show loading state while data is fetched if (!isLoaded || !data) { return <Text>Loading...</Text>; } return ( <SafeAreaView> <Card style={{ margin: 10, padding: 15 }}> <Text style={{ fontSize: 18, fontWeight: 'bold' }}>{data.title}</Text> <Text style={{ marginTop: 5 }}>Score: {data.score}</Text> <Text style={{ marginTop: 5 }}>By: {data.by}</Text> </Card> </SafeAreaView> ); } } export default Hnews;
Option B: Display a List of Stories
If your goal is to build a clone that shows a list (like the actual Hacker News homepage), you need to first fetch the list of top story IDs, then fetch each individual story. Here's how to do that:
import React from 'react'; import { Card, Text } from "react-native-paper"; import { SafeAreaView, ScrollView } from "react-native"; class Hnews extends React.Component { constructor(props) { super(props); this.state = { data: [], isLoaded: false, }; } async componentDidMount() { try { // First get the IDs of top stories const topStoriesRes = await fetch("https://hacker-news.firebaseio.com/v0/topstories.json"); const topStoryIds = await topStoriesRes.json(); // Fetch the first 10 stories (adjust the number as needed) const storyPromises = topStoryIds.slice(0, 10).map(id => fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`).then(res => res.json()) ); const stories = await Promise.all(storyPromises); this.setState({ isLoaded: true, data: stories, // Now data is an array of story objects }); } catch (err) { console.error("Error fetching data:", err); } } render() { const { isLoaded, data } = this.state; if (!isLoaded) { return <Text>Loading...</Text>; } return ( <SafeAreaView> <ScrollView> {data.map((item) => ( // Add a unique key for each list item (required by React) <Card key={item.id} style={{ margin: 10, padding: 15 }}> <Text style={{ fontSize: 16 }}>{item.title}</Text> <Text style={{ marginTop: 5, fontSize: 12, color: '#666' }}> Score: {item.score} | By: {item.by} </Text> </Card> ))} </ScrollView> </SafeAreaView> ); } } export default Hnews;
3. Key Takeaways to Avoid This Error Again
- Always match your state property names in render to what you defined in
this.state - Don't mix
async/awaitand.then()—stick to one style for cleaner, more maintainable code - For lists, make sure your state holds an array before calling
.map() - Add loading states to handle the gap before data is fetched
- Include
try/catchblocks to catch and log API errors gracefully
内容的提问来源于stack exchange,提问作者Gaurav

