快速入门
欢迎阅读 React 文档!此页面将向您介绍您日常使用中 80% 的 React 概念。
你将学习
- 如何创建和嵌套组件
- 如何添加标记和样式
- 如何显示数据
- 如何渲染条件和列表
- 如何响应事件并更新屏幕
- 如何在组件之间共享数据
创建和嵌套组件
React 应用由组件构成。组件是 UI(用户界面)的一部分,具有自己的逻辑和外观。组件可以小到一个按钮,大到整个页面。
React 组件是返回标记的 JavaScript 函数。
function MyButton() {
return (
<button>I'm a button</button>
);
}
现在你已经声明了MyButton
,你可以把它嵌套到另一个组件中。
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
请注意<MyButton />
以大写字母开头。这就是你如何知道它是一个 React 组件。React 组件名称必须始终以大写字母开头,而 HTML 标签必须是小写。
看看结果
function MyButton() { return ( <button> I'm a button </button> ); } export default function MyApp() { return ( <div> <h1>Welcome to my app</h1> <MyButton /> </div> ); }
The export default
关键字指定文件中的主组件。如果您不熟悉某些 JavaScript 语法,MDN 和 javascript.info 提供了很好的参考。
使用 JSX 编写标记
上面看到的标记语法称为JSX。它是可选的,但大多数 React 项目都因其方便性而使用 JSX。我们推荐的所有本地开发工具都开箱即用地支持 JSX。
JSX 比 HTML 更严格。您必须关闭诸如<br />
之类的标签。您的组件也不能返回多个 JSX 标签。您必须将它们包装到一个共享的父级中,例如<div>...</div>
或一个空的<>...</>
包装器。
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
如果您有很多要移植到 JSX 的 HTML,可以使用在线转换器。
添加样式
在 React 中,您使用className
指定 CSS 类。它的作用与 HTML class
属性相同。
<img className="avatar" />
然后,您在单独的 CSS 文件中编写 CSS 规则。
/* In your CSS */
.avatar {
border-radius: 50%;
}
React 没有规定您如何添加 CSS 文件。在最简单的情况下,您将<link>
标签添加到您的 HTML 中。如果您使用构建工具或框架,请查阅其文档以了解如何将 CSS 文件添加到您的项目中。
显示数据
JSX 允许您将标记放入 JavaScript 中。花括号允许您“返回”到 JavaScript,以便您可以嵌入代码中的某些变量并将其显示给用户。例如,这将显示user.name
return (
<h1>
{user.name}
</h1>
);
你也可以从 JSX 属性中“转义到 JavaScript”,但必须使用花括号而不是引号。例如,className="avatar"
将"avatar"
字符串作为 CSS 类传递,但src={user.imageUrl}
读取 JavaScript user.imageUrl
变量的值,然后将该值作为src
属性传递。
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
你也可以在 JSX 花括号内放入更复杂的表达式,例如,字符串连接。
const user = { name: 'Hedy Lamarr', imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg', imageSize: 90, }; export default function Profile() { return ( <> <h1>{user.name}</h1> <img className="avatar" src={user.imageUrl} alt={'Photo of ' + user.name} style={{ width: user.imageSize, height: user.imageSize }} /> </> ); }
在上面的例子中,style={{}}
不是特殊的语法,而是在style={ }
JSX 花括号内的常规{}
对象。当你的样式依赖于 JavaScript 变量时,可以使用style
属性。
条件渲染
在 React 中,没有编写条件的特殊语法。相反,你将使用与编写常规 JavaScript 代码时相同的技术。例如,你可以使用if
语句有条件地包含 JSX。
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
如果你更喜欢更紧凑的代码,可以使用条件?
运算符。 与if
不同,它可以在 JSX 内部工作。
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
当你不需要else
分支时,也可以使用更短的逻辑&&
语法。
<div>
{isLoggedIn && <AdminPanel />}
</div>
所有这些方法也适用于有条件地指定属性。如果你不熟悉其中一些 JavaScript 语法,你可以首先始终使用if...else
。
渲染列表
你将依赖于 JavaScript 特性,例如for
循环 和数组map()
函数 来渲染组件列表。
例如,假设你有一个产品数组。
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
在你的组件内部,使用map()
函数将产品数组转换为<li>
项目数组。
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
注意<li>
有一个key
属性。对于列表中的每个项目,你应该传递一个字符串或数字,以唯一地标识该项目及其同级项目。通常,键应该来自你的数据,例如数据库 ID。React 使用你的键来了解如果你稍后插入、删除或重新排序项目会发生什么。
const products = [ { title: 'Cabbage', isFruit: false, id: 1 }, { title: 'Garlic', isFruit: false, id: 2 }, { title: 'Apple', isFruit: true, id: 3 }, ]; export default function ShoppingList() { const listItems = products.map(product => <li key={product.id} style={{ color: product.isFruit ? 'magenta' : 'darkgreen' }} > {product.title} </li> ); return ( <ul>{listItems}</ul> ); }
响应事件
你可以通过在组件内声明事件处理程序函数来响应事件。
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
注意onClick={handleClick}
末尾没有括号!不要调用事件处理程序函数:你只需要传递它。当用户点击按钮时,React 将调用你的事件处理程序。
更新屏幕
通常,你希望你的组件“记住”一些信息并显示它。例如,你可能想计算按钮被点击的次数。为此,请向你的组件添加状态。
首先,从 React 中导入useState
import { useState } from 'react';
现在你可以在你的组件内声明一个状态变量。
function MyButton() {
const [count, setCount] = useState(0);
// ...
你将从useState
获取两件事:当前状态(count
)和允许你更新它的函数(setCount
)。你可以为它们命名任何名称,但约定是编写[something, setSomething]
。
第一次显示按钮时,count
将为 0
,因为您将 0
传递给了 useState()
。当您想更改状态时,请调用 setCount()
并将新值传递给它。单击此按钮将使计数器递增。
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
React 将再次调用您的组件函数。这一次,count
将为 1
。然后它将变为 2
,依此类推。
如果您多次渲染相同的组件,则每个组件都将拥有自己的状态。请分别点击每个按钮。
import { useState } from 'react'; export default function MyApp() { return ( <div> <h1>Counters that update separately</h1> <MyButton /> <MyButton /> </div> ); } function MyButton() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick}> Clicked {count} times </button> ); }
请注意,每个按钮都“记住”它自己的 count
状态,并且不会影响其他按钮。
使用 Hook
以 use
开头的函数称为 *Hook*。 useState
是 React 提供的内置 Hook。您可以在 API 参考 中找到其他内置 Hook。您还可以通过组合现有的 Hook 来编写自己的 Hook。
Hook 比其他函数更严格。您只能在组件(或其他 Hook)的 *顶部* 调用 Hook。如果您想在条件或循环中使用 useState
,请提取一个新组件并将其放在那里。
组件间共享数据
在前面的示例中,每个 MyButton
都有其独立的 count
,并且当单击每个按钮时,只有被单击的按钮的 count
会发生变化。
但是,通常您需要组件 *共享数据并始终一起更新*。
为了使两个 MyButton
组件显示相同的 count
并一起更新,您需要将状态从各个按钮“向上”移动到包含所有按钮的最近的组件。
在此示例中,它是 MyApp
。
现在,当您单击任一按钮时,MyApp
中的 count
将发生变化,这将更改 MyButton
中的两个计数。以下是如何在代码中表达这一点。
首先,*将状态从* MyButton
*移动到* MyApp
。
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
// ... we're moving code from here ...
}
然后,*将状态从* MyApp
*传递给* 每个 MyButton
,以及共享的点击处理程序。您可以使用 JSX 花括号将信息传递给 MyButton
,就像您之前对 <img>
等内置标签所做的那样。
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Counters that update together</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
像这样传递的信息称为 *props*。现在 MyApp
组件包含 count
状态和 handleClick
事件处理程序,并将 *两者都作为 props 传递给* 每个按钮。
最后,更改 MyButton
以 *读取* 您从其父组件传递的 props。
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}
单击按钮时,onClick
处理程序将被触发。每个按钮的 onClick
prop 都设置为 MyApp
内部的 handleClick
函数,因此其中的代码将运行。该代码调用 setCount(count + 1)
,递增 count
状态变量。新的 count
值作为 prop 传递给每个按钮,因此它们都显示新值。这称为“提升状态”。通过向上移动状态,您已在组件之间共享它。
import { useState } from 'react'; export default function MyApp() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <div> <h1>Counters that update together</h1> <MyButton count={count} onClick={handleClick} /> <MyButton count={count} onClick={handleClick} /> </div> ); } function MyButton({ count, onClick }) { return ( <button onClick={onClick}> Clicked {count} times </button> ); }