跳到主要内容

React 基础

React Native 基于 React 运行,React 是一个流行的开源 JavaScript 库,用于构建用户界面。要充分利用 React Native,了解 React 本身会有所帮助。本节可以帮助您入门或作为复习课程。

我们将介绍 React 的核心概念:

  • 组件
  • JSX
  • props
  • state

如果您想深入了解,我们建议您查阅 React 官方文档

你的第一个组件

本 React 介绍的其余部分将使用猫作为示例:友善、平易近人的生物,需要名字和一家咖啡馆来工作。这是你的第一个 Cat 组件:

具体做法是:要定义 Cat 组件,首先使用 JavaScript 的 import 导入 React 和 React Native 的 Text 核心组件:

tsx
import React from 'react';
import {Text} from 'react-native';

你的组件从一个函数开始:

tsx
const Cat = () => {};

你可以把组件看作蓝图。函数组件返回的任何内容都将渲染成一个 React 元素。React 元素让你能够描述你希望在屏幕上看到的内容。

这里的 Cat 组件将渲染一个 <Text> 元素:

tsx
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};

你可以使用 JavaScript 的 export default 导出你的函数组件,以便在整个应用中使用,如下所示:

tsx
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};

export default Cat;

这是导出组件的众多方法之一。这种导出方式与 Snack Player 配合良好。但是,根据你应用的文件结构,你可能需要使用不同的约定。这篇关于 JavaScript 导入和导出的便捷速查表 可以提供帮助。

现在仔细看看那个 return 语句。<Text>Hello, I am your cat!</Text> 使用了一种 JavaScript 语法,它让编写元素变得方便:JSX。

JSX

React 和 React Native 使用 JSX,这是一种语法,允许你像这样在 JavaScript 中编写元素:<Text>Hello, I am your cat!</Text>。React 文档中有 JSX 的综合指南,你可以查阅以了解更多信息。由于 JSX 就是 JavaScript,你可以在其中使用变量。在这里,你为猫声明了一个名字 name,并使用花括号将其嵌入到 <Text> 中。

任何 JavaScript 表达式都可以在花括号中工作,包括函数调用,例如 {getFullName("Rum", "Tum", "Tugger")}

你可以把花括号想象成在你的 JSX 中创建了一个通向 JS 功能的“传送门”!

因为 JSX 包含在 React 库中,如果你的文件顶部没有 import React from 'react',它将无法工作!

自定义组件

你已经了解了 React Native 的核心组件。React 允许你将这些组件彼此嵌套以创建新组件。这些可嵌套、可复用的组件是 React 范式的核心。

例如,你可以将 TextTextInput 嵌套在下面的 View 内部,React Native 将把它们一起渲染:

开发者须知

如果你熟悉 Web 开发,<View><Text> 可能会让你想起 HTML!你可以把它们看作应用开发中的 <div><p> 标签。

你可以通过使用 <Cat> 组件多次渲染它,并在多个地方使用,而无需重复代码:

任何渲染其他组件的组件都是一个 父组件。在这里,Cafe 是父组件,每个 Cat 都是 子组件。

你可以在你的咖啡馆里放置任意数量的猫。每个 <Cat> 都渲染一个独特的元素——你可以使用 props 进行定制。

Props

Props 是“properties”(属性)的缩写。Props 允许你定制 React 组件。例如,在这里你为每个 <Cat> 传递不同的 name,供 Cat 渲染:

React Native 的大多数核心组件也可以通过 props 进行定制。例如,在使用 Image 时,你向它传递一个名为 source 的 prop 来定义它显示什么图像:

Image许多不同的 props,包括 style,它接受一个包含设计和布局相关属性-值对的 JS 对象。

注意 style 的 `width` 和 `height` 周围的双花括号 {{ }}。在 JSX 中,JavaScript 值用 {} 引用。如果你传递的不是字符串作为 props,例如数组或数字:<Cat food={["fish", "kibble"]} age={2} />,这会很方便。然而,JS 对象用花括号表示:{width: 200, height: 200}。因此,要在 JSX 中传递 JS 对象,你必须将该对象包装在另一对花括号中:{{width: 200, height: 200}}

你可以使用 props 和核心组件 TextImageView 构建许多东西!但是要构建交互式的东西,你需要 state。

State

你可以将 props 视为用于配置组件如何渲染的参数,而 state 则类似于组件的私有数据存储。State 对于处理随时间变化或来自用户交互的数据很有用。State 让你的组件拥有了记忆!

一般来说,在组件渲染时使用 props 来配置它。使用 state 来跟踪你期望随时间变化的任何组件数据。

以下示例发生在一个猫咪咖啡馆里,两只饥饿的猫正在等待被喂食。它们的饥饿度(我们预计会随时间变化,不像它们的名字)存储为 state。要喂食这些猫,请按下它们的按钮——这将更新它们的 state。

你可以通过调用 React 的 useState Hook 来向组件添加 state。Hook 是一种函数,它允许你“钩入”React 特性。例如,useState 是一个 Hook,允许你向函数组件添加 state。你可以在 React 文档中了解更多其他类型的 Hooks。

首先,你需要像这样从 React 导入 useState

tsx
import React, {useState} from 'react';

然后,你通过在其函数内部调用 useState 来声明组件的 state。在此示例中,useState 创建了一个名为 isHungry 的 state 变量:

tsx
const Cat = (props: CatProps) => {
const [isHungry, setIsHungry] = useState(true);
// ...
};

你可以使用 useState 跟踪任何类型的数据:字符串、数字、布尔值、数组、对象。例如,你可以使用 const [timesPetted, setTimesPetted] = useState(0) 来跟踪猫被抚摸的次数!

调用 useState 有两个作用:

  • 它会创建一个带有初始值的“state 变量”——在本例中,state 变量是 isHungry,其初始值为 true
  • 它会创建一个用于设置该 state 变量值的函数——setIsHungry

你使用什么名称并不重要。但将这种模式视为 [<getter>, <setter>] = useState(<initialValue>) 会很方便。

接下来,你添加 Button 核心组件并为其提供一个 onPress prop:

tsx
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>

现在,当有人按下按钮时,onPress 将触发,调用 setIsHungry(false)。这将把 state 变量 isHungry 设置为 false。当 isHungryfalse 时,Buttondisabled prop 被设置为 true,其 title 也会改变:

tsx
<Button
//..
disabled={!isHungry}
title={isHungry ? 'Give me some food, please!' : 'Thank you!'}
/>

你可能已经注意到,尽管 isHungry 是一个 const,但它似乎可以重新赋值!发生的情况是,当调用 setIsHungry 这样的 state 设置函数时,其组件会重新渲染。在这种情况下,Cat 函数将再次运行——而这一次,useState 将提供 isHungry 的下一个值。

最后,将你的猫放到 Cafe 组件中:

tsx
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
};

看到上面出现的 <></> 了吗?这些 JSX 片段是 fragments。相邻的 JSX 元素必须被包裹在一个闭合标签中。Fragments 允许你这样做,而无需嵌套一个额外的、不必要的包装元素(如 View)。


现在你已经了解了 React 和 React Native 的核心组件,让我们通过学习如何处理 <TextInput> 来深入了解其中一些核心组件。