You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native开发Hacker News克隆项目时遭遇Cannot read property of undefined(reading 'map')错误求助

Fixing the "Cannot read property 'map' of undefined" Error in Your Hacker News Clone

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/await and .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/catch blocks to catch and log API errors gracefully

内容的提问来源于stack exchange,提问作者Gaurav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:52:10