前言

本次参加开源鸿蒙跨平台开发学习活动,选择了 React Native 开发 HarmonyOS技术栈,在学习的同时顺便整理成一份系列笔记,记录从环境到开发的全过程。本篇作为第六篇,重点介绍开发GitCode口袋工具APP的ReactNative组件的封装。React Native 在 OpenHarmony 的跨平台开发中,组件(Component)的封装是最基础、也是最常用的能力。本篇记录我在 HarmonyOS NEXT + React Native 环境下,如何从零实现一个“GitCode 仓库列表”中的 Item 组件 —— 支持显示仓库 Logo、名称、Star 按钮、描述、语言类型、收藏数、提交数等。

一、React Native 基础能力概述

1. Components 组件

组件是 React Native 的基本构建单元,它可以理解为一个可复用的 UI 模块。例如按钮、卡片、列表项等都可以构建成组件。
组件有两类:

  • 函数式组件(Function Component) —— 更轻量,配合 Hooks 使用

  • 类组件(Class Component) —— 较少使用,但能处理一些生命周期需求

我们在RN 开发中,通常使用函数式组件。

2. JSX

JSX 是一种“在 JavaScript 中写 UI”的语法,它允许我们像写 XML/HTML 那样描述界面,同时让 UI 与逻辑自然融合。
例如:

<View>
  <Text>Hello React Native</Text>
</View>

JSX 在编译时会被转换成 JavaScript,因此它只是语法糖,但极大提升了开发体验。

3. props(属性)

props 是组件对外暴露的入参,它是只读的,父组件通过 props 给子组件传递数据或回调函数,例如:

<RepoItem name="vue-devui" starCount={779} />

组件内部通过 props.nameprops.starCount 访问。

4. state(状态)

state 是组件内部维护的可变数据,一般用于:

  • 控制 UI 的显示状态

  • 控制按钮点击切换

  • 保存加载、展开、选中等 UI 行为

在函数式组件中通过 useState 管理:

const [isStarred, setIsStarred] = useState(false);

state 更新后界面会自动重新渲染。

二、动手封装:GitCode 仓库列表 Item 组件

我们要封装的组件结构类似下图(GitCode 项目推荐列表):

  • 仓库图标

  • 仓库名称

  • Star 按钮

  • 仓库描述(简介)

  • 编程语言(Vue / TS 等)

  • Stars数

  • 提交数

1.组件设计与属性定义

首先分析组件需要哪些输入:

interface RepoItemProps {
  logo: string;            // 仓库图标
  name: string;            // 仓库名称
  description: string;     // 仓库描述
  language: string;        // 仓库语言类型
  stars: number;           // 收藏数
  commits: number;         // 提交数
  isStarred: boolean;      // 当前用户是否已收藏
  onToggleStar: () => void; // Star 按钮点击事件
}

这些属性构成组件的所有 props。

2.创建 RepoItem 组件

基础组件结构:

import React, { useState } from 'react';
import { View, Text, Image, TouchableOpacity, StyleSheet } from 'react-native';

const RepoItem = ({
  logo,
  name,
  description,
  language,
  stars,
  commits,
  isStarred,
  onToggleStar,
}) => {
  return (
    <View style={styles.container}>
      {/* Logo 区域 */}
      <Image source={{ uri: logo }} style={styles.logo} />

      <View style={styles.content}>
        {/* 标题 + Star 按钮 */}
        <View style={styles.row}>
          <Text style={styles.name}>{name}</Text>

          <TouchableOpacity onPress={onToggleStar} style={styles.starBtn}>
            <Text style={styles.starText}>{isStarred ? '★ Starred' : '☆ Star'}</Text>
          </TouchableOpacity>
        </View>

        {/* 描述 */}
        <Text style={styles.desc}>{description}</Text>

        {/* 语言、Stars、Commits */}
        <View style={styles.footer}>
          <Text style={styles.lang}>{language}</Text>
          <Text style={styles.meta}>⭐ {stars}</Text>
          <Text style={styles.meta}>🔗 {commits}</Text>
        </View>
      </View>
    </View>
  );
};

export default RepoItem;

样式文件:

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    padding: 12,
    borderRadius: 10,
    backgroundColor: '#fff',
    marginBottom: 12,
    elevation: 2,
  },
  logo: {
    width: 46,
    height: 46,
    borderRadius: 8,
    marginRight: 12,
  },
  content: {
    flex: 1,
  },
  row: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  name: {
    fontSize: 16,
    fontWeight: '600',
  },
  starBtn: {
    paddingHorizontal: 10,
    paddingVertical: 4,
    borderWidth: 1,
    borderRadius: 6,
  },
  starText: {
    fontSize: 12,
  },
  desc: {
    marginTop: 6,
    color: '#555',
    fontSize: 13,
  },
  footer: {
    flexDirection: 'row',
    marginTop: 10,
    alignItems: 'center',
  },
  lang: {
    fontSize: 12,
    marginRight: 10,
    backgroundColor: '#f2f2f2',
    paddingHorizontal: 6,
    paddingVertical: 2,
    borderRadius: 4,
  },
  meta: {
    fontSize: 12,
    marginRight: 10,
    color: '#777',
  },
});

3.在列表中使用 RepoItem

你可以在 FlatList 中这样使用:

<FlatList
  data={repoList}
  renderItem={({ item }) => (
    <RepoItem
      logo={item.logo}
      name={item.name}
      description={item.description}
      language={item.language}
      stars={item.stars}
      commits={item.commits}
      isStarred={item.isStarred}
      onToggleStar={() => toggleStar(item.id)}
    />
  )}
  keyExtractor={(item) => item.id.toString()}
/>

这样就实现了一个“GitCode 仓库列表组件”的完整 React Native 封装,同时可以在 OpenHarmony 的 React Native 环境中继续使用。

三、总结

上面从 React Native 的基础能力入手,介绍了 Components、JSX、props、state 这些核心概念。然后通过GitCode仓库列表展示这个需求,完整演示如何基于 OpenHarmony + React Native,封装一个 GitCode 样式的仓库列表 Item 组件。目前还比较简单,接下来我会结合GitCode 的API接口实现动态数据获取和UI的美化。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐