版本: 0.63

React 基础

React 实战教程 深入学习一线大厂必备前端技能,VIP 教程限时免费领取。 立即查看 >

React Native 的基础是React, 是在 web 端非常流行的开源 UI 框架。要想掌握 React Native,先了解 React 框架本身是非常有帮助的。本文旨在为初学者介绍一些 react 的入门知识。

本文主要会探讨以下几个 React 的核心概念:

  • components 组件
  • JSX
  • props 属性
  • state 状态

如果你想更深一步学习,我们建议你阅读React 的官方文档,它也提供有中文版。

尝试编写一个组件#

本文档会用“Cat”这种有个名字和咖啡馆就能开始工作的人畜无害的生物来作为例子。下面是我们的第一个 Cat 组件:

要定义一个Cat组件,第一步要使用import语句来引入React以及React NativeText组件:

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

然后一个简单的函数就可以作为一个组件:

const Cat = () => {};

这个函数的返回值就会被渲染为一个 React 元素。这里Cat会渲染一个<Text>元素:

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

这里我们还使用了export default语句来导出这个组件,以使其可以在其他地方引入使用:

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

上面只是导出组件的写法之一。你还可以看看这篇博客整理handy cheatsheet on JavaScript imports and exports整理的各种不同的写法。

下面我们来看看这个return 语句。<Text>Hello, I am your cat!</Text>是一种简化 React 元素的写法,这种语法名字叫做 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.createElement方法,所以你必须在文件头部引用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 使得我们可以定制组件。比如可以给每只<Cat>一个不同的name

React Native 的绝大多数核心组件都提供了可定制的 props。例如,在使用Image组件时,你可以给它传递一个source属性,用来指定它显示的内容:

Image很多不同的 propsstyle也是其中之一,它接受对象形式的样式和布局键值对。

请留意我们在指定style属性的宽高时所用到的双层括号{{ }}。在 JSX 中,引用 JS 值时需要使用{}括起来。在你需要传递非字符串值(比如数组或者数字)的时候会经常用到这种写法:<Cat food={["fish", "kibble"]} /> age={2}。然而我们在 JS 中定义一个对象时,本来需要用括号括起来:{width: 200, height: 200}。因此要在 JSX 中传递一个 JS 对象值的时候,就必须用到两层括号:{{width: 200, height: 200}}

使用核心组件Text, Image以及View搭配 props 已经可以做不少东西了!但是如果想要做一些用户交互,那我们还需要用到状态(state)。

State 状态#

如果把 props 理解为定制组件渲染的参数, 那么state就像是组件的私人数据记录。状态用于记录那些随时间或者用户交互而变化的数据。状态使组件拥有了记忆!

按惯例来说,props 用来配置组件的第一次渲染(初始状态)。Use state to keep track of any component data that you expect to change over time. The following example takes place in a cat cafe where two hungry cats are waiting to be fed. Their hunger, which we expect to change over time (unlike their names), is stored as state. To feed the cats, press their buttons—which will update their state.

你可以使用React 的useState Hook来为组件添加状态。Hook (钩子)是一种特殊的函数,可以让你“钩住”一些 React 的特性。例如useState可以在函数组件中添加一个“状态钩子”,在函数组件重新渲染执行的时候能够保持住之前的状态。要了解更多,可以阅读React 中有关 Hook 的文档

首先要从 react 中引入useState

import React, { useState } from 'react';

然后可以通过在函数内调用useState来为组件声明状态。In this example, useState creates an isHungry state variable:

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

你可以使用useState来记录各种类型的数据: strings, numbers, Booleans, arrays, objects。例如你可以这样来记录猫咪被爱抚的次数:const [timesPetted, setTimesPetted] = useState(0)useState实质上做了两件事情:

  • 创建一个“状态变量”,并赋予一个初始值。上面例子中的状态变量是isHungry,初始值为true
  • 同时创建一个函数用于设置此状态变量的值——setIsHungry

取什么名字并不重要。但脑海中应该形成这样一种模式:[<取值>, <设值>] = useState(<初始值>).

下面我们添加一个按钮Button组件,并给它一个onPress的 prop:

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

现在当用户点击按钮时,onPress函数会被触发,从而调用setIsHungry(false)。此时状态变量isHungry就被设为了false。当isHungry为 false 的时候,Buttondisabled属性就变成了true ,其title也相应变化:

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

你可能注意到虽然isHungry使用了常量关键字const,但它看起来还是可以修改!简单来说,当你调用setIsHungry这样的设置状态的函数时,其所在的组件会重新渲染。在这里,这整个Cat函数都会从头重新执行一遍。重新执行的时候,useState会返回给我们新设置的值。

最后再把猫咪放进Cafe组件:

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

注意到上面的<></>了吗? 这一对 JSX 标签称为Fragments(片段)。由于 JSX 的语法要求根元素必须为单个元素,如果我们需要在根节点处并列多个元素,在此前不得不额外套一个没有实际用处的View。但有了 Fragment 后就不需要引入额外的容器视图了。


现在你应该已经差不多了解 React 和 React Native 的核心组件与思想了。下面可以试着深入学习一些核心组件的用法,比如如何处理文本输入<TextInput>


本文档贡献者:sunnylqm(76.07%), sunnylqm(23.74%), git(0.19%)#