React 基础
React Native 运行于 React 之上,这是一个使用 JavaScript 构建用户界面的流行开源库。为了充分利用 React Native,理解 React 本身会有所帮助。本节可以帮助你入门,也可以作为复习课程。
我们将涵盖 React 背后的核心概念:
- 组件
- JSX
- props
- state
如果你想深入挖掘,我们鼓励你查看 React 官方文档。
你的第一个组件
这篇 React 介绍的其余部分将在示例中使用猫:友好、亲切的生物,它们需要名字和工作的咖啡馆。这是你的第一个 Cat 组件:
做法如下:要定义你的 Cat 组件,首先使用 JavaScript 的 import 导入 React 和 React Native 的 Text 核心组件:
import React from 'react';
import {Text} from 'react-native';
你的组件始于一个函数:
const Cat = () => {};
你可以将组件视为蓝图。函数组件返回的任何内容都会作为 React 元素 渲染。React 元素让你描述你想在屏幕上看到的内容。
此处 Cat 组件将渲染一个 <Text> 元素:
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};
你可以使用 JavaScript 的 export default 导出你的函数组件,以便在整个应用中使用,如下所示:
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")}:
- TypeScript
- JavaScript
你可以将花括号视为在 JSX 中创建了一个通往 JS 功能的门户!
因为 JSX 包含在 React 库中,如果你的文件顶部没有
import React from 'react',它将无法工作!
自定义组件
你已经见过 React Native 的核心组件。React 允许你将这些组件相互嵌套以创建新组件。这些可嵌套、可复用的组件是 React 范式的核心。
例如,你可以在下面的 View 中嵌套 Text 和 TextInput,React Native 会将它们一起渲染:
开发者注
- Android
- Web
如果你熟悉 Web 开发,
<View>和<Text>可能会让你想起 HTML!你可以将它们视为应用开发中的<div>和<p>标签。
在 Android 上,你通常将视图放在
LinearLayout、FrameLayout、RelativeLayout等内部,以定义视图的子元素如何在屏幕上排列。在 React Native 中,View使用 Flexbox 来进行子元素布局。你可以在 我们的 Flexbox 布局指南 中了解更多。
你可以通过使用 <Cat> 多次并在多处渲染此组件,而无需重复代码:
任何渲染其他组件的组件都是 父组件。 此处,Cafe 是父组件,每个 Cat 都是 子组件。
你可以在咖啡馆里放任意数量的猫。每个 <Cat> 渲染一个独特的元素——你可以使用 props 对其进行定制。
Props
Props 是"properties"的缩写。Props 允许你定制 React 组件。例如,这里你传递给每个 <Cat> 一个不同的 name 供 Cat 渲染:
- TypeScript
- JavaScript
大多数 React Native 的核心组件也可以用 props 定制。例如,使用 Image 时,你传递一个名为 source 的 prop 来定义它显示什么图像:
Image 有 许多不同的 props,包括 style,它接受一个包含设计和布局相关属性 - 值对的 JS 对象。
注意围绕
style宽度和高度的双花括号{{ }}。在 JSX 中,JavaScript 值使用{}引用。如果你传递的不是字符串而是其他内容作为 props,比如数组或数字,这很方便:<Cat food={["fish", "kibble"]} age={2} />。但是,JS 对象也 同样 用花括号表示:{width: 200, height: 200}。因此,要在 JSX 中传递 JS 对象,你必须将对象包裹在 另一对 花括号中:{{width: 200, height: 200}}
你可以使用 props 和核心组件 Text、Image 和 View 构建许多东西!但要构建交互式的東西,你需要 state。
State
虽然你可以将 props 视为用于配置组件渲染方式的参数,但 state 就像组件的个人数据存储。State 对于处理随时间变化的数据或来自用户交互的数据很有用。State 赋予你的组件记忆!
作为一般规则,使用 props 在组件渲染时配置它。使用 state 跟踪任何你预期会随时间变化的组件数据。
以下示例发生在一家猫咖啡馆,两只饥饿的猫正等待喂食。它们的饥饿感(我们预期会随时间变化,与名字不同)被存储为 state。要喂猫,按下它们的按钮——这将更新它们的 state。
你可以通过调用 React 的 useState Hook 向组件添加 state。Hook 是一种让你能够"钩入"React 功能的函数。例如,useState 是一个允许你向函数组件添加 state 的 Hook。你可以在 React 文档中了解更多关于其他种类 Hook 的信息。
- TypeScript
- JavaScript
首先,你需要像这样从 React 导入 useState:
import React, {useState} from 'react';
然后通过在组件函数内调用 useState 来声明组件的 state。在此示例中,useState 创建一个 isHungry state 变量:
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:
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>
现在,当有人按下按钮时,onPress 将触发,调用 setIsHungry(false)。这将 state 变量 isHungry 设置为 false。当 isHungry 为 false 时,Button 的 disabled prop 设置为 true,其 title 也会改变:
<Button
//..
disabled={!isHungry}
title={isHungry ? 'Give me some food, please!' : 'Thank you!'}
/>
你可能已经注意到,虽然
isHungry是一个 const,但它似乎可以重新赋值!发生的情况是,当像setIsHungry这样的 state 设置函数被调用时,其组件将重新渲染。在这种情况下,Cat函数将再次运行——这次,useState将给我们isHungry的下一个值。
最后,将你的猫放入 Cafe 组件中:
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
};
看到上面的
<>和</>了吗?这些 JSX 片段是 fragments。相邻的 JSX 元素必须包裹在一个封闭标签中。Fragments 让你这样做而无需嵌套额外的、不必要的包裹元素,如View。
现在你已经了解了 React 和 React Native 的核心组件,让我们通过查看 处理 <TextInput> 来更深入地研究其中一些核心组件。