快速开始
欢迎使用 React 文档!本页面将向你介绍你日常使用中 80% 的 React 概念。
🌐 Welcome to the React documentation! This page will give you an introduction to 80% of the React concepts that you will use on a daily basis.
你将学习到
- 如何创建和嵌套组件
- 如何添加标记和样式
- 如何显示数据
- 如何渲染条件和列表
- 如何响应事件和更新屏幕
- 如何在组件之间共享数据
创建和嵌套组件
🌐 Creating and nesting components
React 应用由 组件 构成。组件是用户界面(UI)的一部分,具有自己的逻辑和外观。组件可以小到一个按钮,也可以大到整整一页。
🌐 React apps are made out of components. A component is a piece of the UI (user interface) that has its own logic and appearance. A component can be as small as a button, or as large as an entire page.
React 组件是返回标记的 JavaScript 函数:
🌐 React components are JavaScript functions that return markup:
function MyButton() {
return (
<button>I'm a button</button>
);
}既然你已经声明了 MyButton,你可以将它嵌套到另一个组件中:
🌐 Now that you’ve declared MyButton, you can nest it into another component:
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}注意 <MyButton /> 以大写字母开头。这就是你知道它是一个 React 组件的方式。React 组件名称必须始终以大写字母开头,而 HTML 标签必须小写。
🌐 Notice that <MyButton /> starts with a capital letter. That’s how you know it’s a React component. React component names must always start with a capital letter, while HTML tags must be lowercase.
看看结果:
🌐 Have a look at the result:
function MyButton() { return ( <button> I'm a button </button> ); } export default function MyApp() { return ( <div> <h1>Welcome to my app</h1> <MyButton /> </div> ); }
export default 关键字指定文件中的主要组件。如果你对某些 JavaScript 语法不熟悉, MDN 和 javascript.info 都有很好的参考资料。
🌐 The export default keywords specify the main component in the file. If you’re not familiar with some piece of JavaScript syntax, MDN and javascript.info have great references.
使用 JSX 编写标记
🌐 Writing markup with JSX
你在上面看到的标记语法叫做 JSX。它是可选的,但大多数 React 项目都使用 JSX 因其方便性。我们推荐的所有本地开发工具默认都支持 JSX。
🌐 The markup syntax you’ve seen above is called JSX. It is optional, but most React projects use JSX for its convenience. All of the tools we recommend for local development support JSX out of the box.
JSX 比 HTML 更严格。你必须关闭像 <br /> 这样的标签。你的组件也不能返回多个 JSX 标签。你必须将它们封装在一个共享的父元素中,比如一个 <div>...</div> 或一个空的 <>...</> 封装器:
🌐 JSX is stricter than HTML. You have to close tags like <br />. Your component also can’t return multiple JSX tags. You have to wrap them into a shared parent, like a <div>...</div> or an empty <>...</> wrapper:
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}如果你有大量的 HTML 需要转换为 JSX,你可以使用一个在线转换器。
🌐 If you have a lot of HTML to port to JSX, you can use an online converter.
添加样式
🌐 Adding styles
在 React 中,你使用 className 指定一个 CSS 类。它的工作方式与 HTML class 属性相同:
🌐 In React, you specify a CSS class with className. It works the same way as the HTML class attribute:
<img className="avatar" />然后在单独的 CSS 文件中为其编写 CSS 规则:
🌐 Then you write the CSS rules for it in a separate CSS file:
/* In your CSS */
.avatar {
border-radius: 50%;
}React 并没有规定如何添加 CSS 文件。在最简单的情况下,你可以在 HTML 中添加一个 <link> 标签。如果你使用构建工具或框架,请查阅其文档以了解如何将 CSS 文件添加到你的项目中。
🌐 React does not prescribe how you add CSS files. In the simplest case, you’ll add a <link> tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project.
显示数据
🌐 Displaying data
JSX 让你可以在 JavaScript 中加入标记。大括号让你“回到” JavaScript,从而可以嵌入代码中的某个变量并显示给用户。例如,这将显示 user.name:
🌐 JSX lets you put markup into JavaScript. Curly braces let you “escape back” into JavaScript so that you can embed some variable from your code and display it to the user. For example, this will display user.name:
return (
<h1>
{user.name}
</h1>
);你也可以从 JSX 属性中“跳入 JavaScript”,但是你必须使用大括号而不是引号。例如,className="avatar" 将 "avatar" 字符串作为 CSS 类传递,而 src={user.imageUrl} 则读取 JavaScript 的 user.imageUrl 变量值,然后将该值作为 src 属性传递:
🌐 You can also “escape into JavaScript” from JSX attributes, but you have to use curly braces instead of quotes. For example, className="avatar" passes the "avatar" string as the CSS class, but src={user.imageUrl} reads the JavaScript user.imageUrl variable value, and then passes that value as the src attribute:
return (
<img
className="avatar"
src={user.imageUrl}
/>
);你也可以在 JSX 大括号中放入更复杂的表达式,例如,字符串连接:
🌐 You can put more complex expressions inside the JSX curly braces too, for example, string concatenation:
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 属性。
🌐 In the above example, style={{}} is not a special syntax, but a regular {} object inside the style={ } JSX curly braces. You can use the style attribute when your styles depend on JavaScript variables.
条件渲染
🌐 Conditional rendering
在 React 中,写条件语句没有特殊的语法。相反,你将使用编写普通 JavaScript 代码时使用的相同技术。例如,你可以使用 if 语句有条件地包含 JSX:
🌐 In React, there is no special syntax for writing conditions. Instead, you’ll use the same techniques as you use when writing regular JavaScript code. For example, you can use an if statement to conditionally include JSX:
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);如果你更喜欢更紧凑的代码,你可以使用条件 ? 运算符。与 if 不同,它可以在 JSX 内部使用:
🌐 If you prefer more compact code, you can use the conditional ? operator. Unlike if, it works inside JSX:
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>当你不需要 else 分支时,你也可以使用更短的 逻辑 && 语法:
🌐 When you don’t need the else branch, you can also use a shorter logical && syntax:
<div>
{isLoggedIn && <AdminPanel />}
</div>所有这些方法也适用于有条件地指定属性。如果你不熟悉其中的一些 JavaScript 语法,你可以先从始终使用 if...else 开始。
🌐 All of these approaches also work for conditionally specifying attributes. If you’re unfamiliar with some of this JavaScript syntax, you can start by always using if...else.
渲染列表
🌐 Rendering lists
你将依赖 JavaScript 的特性,如 for 循环 和 数组 map() 函数 来渲染组件列表。
🌐 You will rely on JavaScript features like for loop and the array map() function to render lists of components.
例如,假设你有一系列产品:
🌐 For example, let’s say you have an array of products:
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];在你的组件内部,使用 map() 函数将产品数组转换为 <li> 项数组:
🌐 Inside your component, use the map() function to transform an array of products into an array of <li> items:
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);注意 <li> 拥有 key 属性。对于列表中的每一项,你应该传递一个字符串或数字,以唯一标识该项在其同级项中的位置。通常,key 应该来自你的数据,例如数据库 ID。React 使用你的 key 来了解当你之后插入、删除或重新排序这些项时发生了什么。
🌐 Notice how <li> has a key attribute. For each item in a list, you should pass a string or a number that uniquely identifies that item among its siblings. Usually, a key should be coming from your data, such as a database ID. React uses your keys to know what happened if you later insert, delete, or reorder the items.
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> ); }
响应事件
🌐 Responding to events
你可以通过在组件内部声明事件处理函数来响应事件:
🌐 You can respond to events by declaring event handler functions inside your components:
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}注意 onClick={handleClick} 末尾没有括号!不要去 调用 事件处理函数:你只需要 传递它下去。当用户点击按钮时,React 会调用你的事件处理函数。
🌐 Notice how onClick={handleClick} has no parentheses at the end! Do not call the event handler function: you only need to pass it down. React will call your event handler when the user clicks the button.
更新屏幕
🌐 Updating the screen
通常,你会希望你的组件“记住”一些信息并显示它。例如,也许你想计算按钮被点击的次数。为此,你需要在组件中添加状态。
🌐 Often, you’ll want your component to “remember” some information and display it. For example, maybe you want to count the number of times a button is clicked. To do this, add state to your component.
首先,从 React 导入 useState :
🌐 First, import useState from React:
import { useState } from 'react';现在你可以在你的组件内声明一个状态变量:
🌐 Now you can declare a state variable inside your component:
function MyButton() {
const [count, setCount] = useState(0);
// ...你将从 useState 获得两样东西:当前状态 (count),以及允许你更新它的函数 (setCount)。你可以给它们任何名字,但惯例是写作 [something, setSomething]。
🌐 You’ll get two things from useState: the current state (count), and the function that lets you update it (setCount). You can give them any names, but the convention is to write [something, setSomething].
按钮第一次显示时,count 将是 0,因为你将 0 传递给了 useState()。当你想要更改状态时,调用 setCount() 并传递新的值给它。点击此按钮将增加计数器:
🌐 The first time the button is displayed, count will be 0 because you passed 0 to useState(). When you want to change state, call setCount() and pass the new value to it. Clicking this button will increment the counter:
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}React 将再次调用你的组件函数。这一次,count 将是 1。然后它将是 2。如此类推。
🌐 React will call your component function again. This time, count will be 1. Then it will be 2. And so on.
如果你多次渲染同一个组件,每个组件都会有自己的状态。分别点击每个按钮:
🌐 If you render the same component multiple times, each will get its own state. Click each button separately:
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 状态,并且不会影响其他按钮。
🌐 Notice how each button “remembers” its own count state and doesn’t affect other buttons.
使用钩子
🌐 Using Hooks
以 use 开头的函数称为 Hooks。useState 是 React 提供的内置 Hook。你可以在 API 参考 中找到其他内置 Hooks。你也可以通过组合现有的 Hooks 来编写自己 的 Hooks。
🌐 Functions starting with use are called Hooks. useState is a built-in Hook provided by React. You can find other built-in Hooks in the API reference. You can also write your own Hooks by combining the existing ones.
Hooks 比其他函数更有约束。你只能在组件的顶部(或其他 Hooks)调用 Hooks。如果你想在条件或循环中使用 useState,请提取一个新组件并将其放在那里。
🌐 Hooks are more restrictive than other functions. You can only call Hooks at the top of your components (or other Hooks). If you want to use useState in a condition or a loop, extract a new component and put it there.
在组件之间共享数据
🌐 Sharing data between components
在前面的示例中,每个 MyButton 都有自己独立的 count,当每个按钮被点击时,只有被点击按钮对应的 count 会改变:
🌐 In the previous example, each MyButton had its own independent count, and when each button was clicked, only the count for the button clicked changed:


最初,每个 MyButton 的 count 状态是 0
🌐 Initially, each MyButton’s count state is 0


第一个 MyButton 将其 count 更新为 1
🌐 The first MyButton updates its count to 1
然而,通常你需要组件共享数据并始终一起更新。
🌐 However, often you’ll need components to share data and always update together.
为了让两个 MyButton 组件显示相同的 count 并一起更新,你需要将状态从各个按钮“向上”移动到包含它们的最近的组件。
🌐 To make both MyButton components display the same count and update together, you need to move the state from the individual buttons “upwards” to the closest component containing all of them.
在这个例子中,它是 MyApp:
🌐 In this example, it is MyApp:


最初,MyApp 的 count 状态是 0,并传递给两个子节点
🌐 Initially, MyApp’s count state is 0 and is passed down to both children


点击时,MyApp 会将其 count 状态更新为 1,并将其传递给两个子组件
🌐 On click, MyApp updates its count state to 1 and passes it down to both children
现在当你点击任意一个按钮时,MyApp 中的 count 会改变,这将改变 MyButton 中的两个计数。下面是你如何在代码中表示这一点。
🌐 Now when you click either button, the count in MyApp will change, which will change both of the counts in MyButton. Here’s how you can express this in code.
首先,将状态从 MyButton 移到 MyApp:
🌐 First, move the state up from MyButton into 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> 所做的那样:
🌐 Then, pass the state down from MyApp to each MyButton, together with the shared click handler. You can pass information to MyButton using the JSX curly braces, just like you previously did with built-in tags like <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 传递给每个按钮。
🌐 The information you pass down like this is called props. Now the MyApp component contains the count state and the handleClick event handler, and passes both of them down as props to each of the buttons.
最后,将 MyButton 改为 读取 你从父组件传递的 props:
🌐 Finally, change MyButton to read the props you have passed from its parent component:
function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}当你点击按钮时,onClick 处理程序会触发。每个按钮的 onClick 属性都在 MyApp 内被设置为 handleClick 函数,因此其中的代码会运行。该代码调用 setCount(count + 1),增加 count 状态变量。新的 count 值作为属性传递给每个按钮,因此它们都会显示新值。这称为“提升状态”。通过将状态上移,你已经在组件之间共享了它。
🌐 When you click the button, the onClick handler fires. Each button’s onClick prop was set to the handleClick function inside MyApp, so the code inside of it runs. That code calls setCount(count + 1), incrementing the count state variable. The new count value is passed as a prop to each button, so they all show the new value. This is called “lifting state up”. By moving state up, you’ve shared it between components.
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> ); }