如何使用 JavaScript 和 React Native News API 构建新闻应用程序 news.js App.js Article.js

2025-05-27

如何使用 JavaScript 和 React Native 构建新闻应用程序

新闻API

新闻.js

App.js

文章.js

构建应用程序的要求:

  • 对 JavaScript 语言有基本的了解。
  • Node.jsreact native
  • 使用的库:moment、react-native、react-native-elements。

如果您不熟悉这些资源,请不要担心——它们非常容易使用。

我们将在文章中讨论的主题是:

  • 新闻API
  • 获取 API
  • 平面列表
  • 下拉刷新
  • 链接

还有更多……那就开始吧!你可以在这里
找到完整的项目仓库

新闻API

一个简单易用的 API,可返回目前网络上实时更新的标题和文章的 JSON 元数据。—  NewsAPI.org

首先,您应该继续注册 News Api 以获取免费的 apiKey(您的身份验证密钥)。

创建一个新的 React Native 项目,并为其命名news_app(或任何你想要的名称)。在项目目录中,新建一个文件夹并将其命名为srcsrc 文件夹中,创建一个名为 news.js 的新文件。在这个文件中,我们将从 News API 获取包含标题的 JSON。srccomponents
截屏

新闻.js

const url =
  "https://newsapi.org/v2/top-headlines?country=us&apiKey=YOUR_API_KEY_HERE";

export async function getNews() {
  let result = await fetch(url).then(response => response.json());
  return result.articles;
}
Enter fullscreen mode Exit fullscreen mode

请务必YOUR_API_KEY_HERE使用您自己的 API 密钥进行替换。有关新闻 API 的更多信息,请参阅newsapi 文档

现在我们声明一个getNews函数,它将为我们获取文章。导出该函数,以便我们可以在App.js文件中使用它。

App.js

import React from 'react';
import { FlatList } from 'react-native';

// Import getNews function from news.js
import { getNews } from './src/news';
// We'll get to this one later
import Article from './src/components/Article';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { articles: [], refreshing: true };
    this.fetchNews = this.fetchNews.bind(this);
  }
  // Called after a component is mounted
  componentDidMount() {
    this.fetchNews();
   }

  fetchNews() {
    getNews()
      .then(articles => this.setState({ articles, refreshing: false }))
      .catch(() => this.setState({ refreshing: false }));
  }

  handleRefresh() {
    this.setState(
      {
        refreshing: true
    },
      () => this.fetchNews()
    );
  }

  render() {
    return (
      <FlatList
        data={this.state.articles}
        renderItem={({ item }) => <Article article={item} />}
        keyExtractor={item => item.url}
        refreshing={this.state.refreshing}
        onRefresh={this.handleRefresh.bind(this)}
      />
  );
  }
}
Enter fullscreen mode Exit fullscreen mode

在构造函数中,我们定义了初始状态。articles它将在我们获取文章后存储它们,并refreshing帮助我们刷新动画。请注意,我设置为refreshingtrue因为当我们启动应用程序时,我们希望动画在加载文章时启动。
componentDidMount在组件挂载后立即调用。在其中我们调用fetchNews方法。

componentDidMount() {
  this.fetchNews();
}
Enter fullscreen mode Exit fullscreen mode

fetchNews我们调用getNews()方法会返回一个 Promise。因此,我们使用.then()一个接受回调函数的方法,而回调函数又接受一个参数(即文章)。

现在将状态中的文章赋值给articles参数。我之所以只输入了articles{articles:articles} ,是因为这是新的 ES6 语法,意思是 {articles:articles} ,然后我们设置refreshingfalse来停止旋转动画。

fetchNews() {
  getNews().then(
      articles => this.setState({ articles, refreshing: false })
  ).catch(() => this.setState({ refreshing: false }));
}
Enter fullscreen mode Exit fullscreen mode

.catch()在被驳回的案件中被称为。

handleRefresh启动旋转动画并调用fetchNews()。我们传递() => this.fetchNews(),因此在分配状态后会立即调用它。

handleRefresh() {
  this.setState({ refreshing: true },() => this.fetchNews());
}
Enter fullscreen mode Exit fullscreen mode

在该render方法中,我们返回一个FlatList元素。然后我们传递一些 props。data是来自 的文章数组this.state。 它renderItem接受一个函数来渲染数组中的每个项目,但在我们的例子中,它只返回Article我们之前导入的组件(我们稍后会讲到)。我们将该article项目作为 prop 传递,以便稍后在该组件中使用。

文章.js

创建src/components一个新的 JavaScript 文件并调用它Article.js

让我们首先使用 npm: 安装两个简单的库react-native-elements,这为我们提供了一些可以使用的预制组件,并且moment可以节省我们的时间。

使用终端/cmd 运行:

npm install --save react-native-elements moment

在 Article.js 中:

import React from 'react';
import { View, Linking, TouchableNativeFeedback } from 'react-native';
import { Text, Button, Card, Divider } from 'react-native-elements';
import moment from 'moment';

export default class Article extends React.Component {
  render() {
    const {
      title,
      description,
      publishedAt,
      source,
      urlToImage,
      url
    } = this.props.article;
    const { noteStyle, featuredTitleStyle } = styles;
    const time = moment(publishedAt || moment.now()).fromNow();
    const defaultImg =
      'https://wallpaper.wiki/wp-content/uploads/2017/04/wallpaper.wiki-Images-HD-Diamond-Pattern-PIC-WPB009691.jpg';

    return (
      <TouchableNativeFeedback
        useForeground
        onPress={() => Linking.openURL(url)}
      >
        <Card
          featuredTitle={title}
          featuredTitleStyle={featuredTitleStyle}
          image={{
            uri: urlToImage || defaultImg
          }}
        >
          <Text style={{ marginBottom: 10 }}>
            {description || 'Read More..'}
          </Text>
          <Divider style={{ backgroundColor: '#dfe6e9' }} />
          <View
            style={{ flexDirection: 'row', justifyContent: 'space-between' }}
          >
            <Text style={noteStyle}>{source.name.toUpperCase()}</Text>
            <Text style={noteStyle}>{time}</Text>
          </View>
        </Card>
      </TouchableNativeFeedback>
    );
  }
}

const styles = {
  noteStyle: {
    margin: 5,
    fontStyle: 'italic',
    color: '#b2bec3',
    fontSize: 10
  },
  featuredTitleStyle: {
    marginHorizontal: 5,
    textShadowColor: '#00000f',
    textShadowOffset: { width: 3, height: 3 },
    textShadowRadius: 3
  }
};
Enter fullscreen mode Exit fullscreen mode

这里有很多事情要做。首先,我们先解构proparticlestyles类下定义的对象。

我们render定义time来存储文章的发布时间。我们使用moment库将日期转换为发布时间之后的时间,如果,则将publishedAt或 从现在开始的时间转换为publishedAtnull

defaultImg被分配一个图像URL,以防文章图像的URL是null

render方法返回TouchableNativeFeedbackTouchableOpacity如果在您的平台上无法使用,请使用该方法)用于处理用户按下卡片时的操作。我们向其传递了一些 props:useForground它告诉元素在卡片上显示涟漪效果时使用前景,以及onPress,它接受一个函数并在用户按下卡片时执行该函数。我们传递() => Linking.openUrl(url)的 仅仅是在用户按下卡片时打开完整文章的 URL。

这张卡片需要三个 props:featuredTitle一个漂亮的标题,放在图片上方(title如果需要,也可以用其他标题代替)featuredTitleStyle,一个是 image,用于设置图片的样式;另一个是 image,它是来自 article props 的文章图片。否则,如果是null,则使用defaultImg

..
  featuredTitle={title}
  featuredTitleStyle={featuredTitleStyle}
  image={{ uri: urlToImage || defaultImg }}
..
Enter fullscreen mode Exit fullscreen mode

至于text元素,它将保存文章的描述。

<Text style={{ marginBottom: 10 }}>{description}</Text>

我们添加了一个divider来将描述与时间和源名称分开。

<Divider style={{ backgroundColor: '#dfe6e9' }} />

在 下方Divider,我们有一个View包含来源名称和文章发布时间的。

..
<View 
  style={{ flexDirection: row, justifyContent: space-between }} > 
  <Text style={noteStyle}>{source.name.toUpperCase()}</Text>
  <Text style={noteStyle}>{time}</Text>
</View>
..
Enter fullscreen mode Exit fullscreen mode

之后class,我们定义了这些组件的样式。

现在,如果我们运行该应用程序:我们可以刷新应用程序 。好了!该应用程序的源代码可以在 GitHub 上找到,可以对其进行改进并发出拉取请求😄。
截屏

截屏

希望你喜欢我的文章!如果你有任何疑问,欢迎评论或在推特上联系我,我一定会提供帮助 :)

也别忘了分享这篇文章😄👇。

文章来源:https://dev.to/msal/how-to-build-a-news-app-with-react-native-4ifd
PREV
我们如何利用“Ship Small”在 GitHub 上快速构建新功能
NEXT
Tailwind CSS 用户?读读这个!