React 基础
React Native 运行在 React 之上,这是一个流行的用于使用 JavaScript 构建用户界面的开源库。为了充分利用 React Native,理解 React 本身会有所帮助。本节可以帮助你入门,也可以作为复习课程。
我们将涵盖 React 背后的核心概念:
- 组件
- JSX
- props
- state
如果你想深入挖掘,我们鼓励你查看 React 官方文档。
你的第一个组件
这篇 React 介绍的其余部分将以猫为例:友好、亲切的生物,它们需要名字和工作的咖啡馆。这是你的第一个 Cat 组件:
Here is how you do it: To define your Cat component, first use JavaScript’s import to import React Native’s Text Core Component:
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 功能的门户!
自定义组件
你已经见过 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 {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!'}
/>
You might’ve noticed that although isHungry is a const, it is seemingly reassignable! The const keyword here does not mean that the state itself is immutable. Rather, it means that the reference to the object, that contains the state and the function to update it, will not change.
What is happening is when a state-setting function like setIsHungry is called, its component will re-render. In this case the Cat function will run again—and this time, useState will give us the next value of isHungry.
最后,将你的猫放入 Cafe 组件中:
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
};
看到上面的 <> 和 </> 了吗?这些 JSX 片段是 片段。相邻的 JSX 元素必须包裹在一个封闭标签中。片段让你这样做而无需嵌套额外的、不必要的包装元素,如 View。
现在你已经涵盖了 React 和 React Native 的核心组件,让我们通过查看 处理 <TextInput> 来更深入地探讨其中一些核心组件。