React 基础
React Native 运行在 React 之上,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 是“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
是一个 Hook,它允许你为函数组件添加 state。你可以在 React 文档中了解其他类型的 Hooks。
- 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
会做两件事:
- 它会创建一个带初始值的“状态变量”——在这个例子中,状态变量是
isHungry
,它的初始值是true
。 - 它会创建一个函数来设置该状态变量的值——
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>
来更深入地了解其中一些核心组件。