From b0835f3fcf0b768f86fde1799710b6752b69c62e Mon Sep 17 00:00:00 2001 From: Sylvia Zhang Date: Tue, 28 Feb 2023 09:58:38 +0800 Subject: [PATCH] [Beta]: docs(cn): translate learn/passing-props-to-a-component.md into Chinese (#647) * fix: correct some spelling mistakes in handling-events.md * [Beta]: docs(cn): translate learn/passing-props-to-a-component.md * resolve suggestions from rottenpen * resolve suggestions from rottenpen * remove extra spaces --------- Co-authored-by: Sylvia Zhang --- .../learn/passing-props-to-a-component.md | 160 +++++++++--------- 1 file changed, 81 insertions(+), 79 deletions(-) diff --git a/beta/src/content/learn/passing-props-to-a-component.md b/beta/src/content/learn/passing-props-to-a-component.md index 111fa89bdc..cb95aa5aa1 100644 --- a/beta/src/content/learn/passing-props-to-a-component.md +++ b/beta/src/content/learn/passing-props-to-a-component.md @@ -1,26 +1,29 @@ --- -title: Passing Props to a Component +title: 将 Props 传递给组件 +translators: + - SylviaZ89 + - rottenpen --- -React components use *props* to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions. +React 组件使用 *props* 来互相通信。每个父组件都可以提供 props 给它的子组件,从而将一些信息传递给它。Props 可能会让你想起 HTML 属性,但你可以通过它们传递任何 JavaScript 值,包括对象、数组和函数。 -* How to pass props to a component -* How to read props from a component -* How to specify default values for props -* How to pass some JSX to a component -* How props change over time +* 如何向组件传递 props +* 如何从组件读取 props +* 如何为 props 指定默认值 +* 如何给组件传递 JSX +* Props 如何随时间变化 -## Familiar props {/*familiar-props*/} +## 熟悉的 props {/*familiar-props*/} -Props are the information that you pass to a JSX tag. For example, `className`, `src`, `alt`, `width`, and `height` are some of the props you can pass to an ``: +Props 是你传递给 JSX 标签的信息。例如,`className`、`src`、`alt`、`width` 和 `height` 便是一些可以传递给 `` 的 props: @@ -51,11 +54,11 @@ body { min-height: 120px; } -The props you can pass to an `` tag are predefined (ReactDOM conforms to [the HTML standard](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element)). But you can pass any props to *your own* components, such as ``, to customize them. Here's how! +你可以传递给 `` 标签的 props 是预定义的(ReactDOM 符合 [HTML 标准](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element))。但是你可以将任何 props 传递给 *你自己的* 组件,例如 `` ,以便自定义它们。 就像这样! -## Passing props to a component {/*passing-props-to-a-component*/} +## 向组件传递 props {/*passing-props-to-a-component*/} -In this code, the `Profile` component isn't passing any props to its child component, `Avatar`: +在这段代码中, `Profile` 组件没有向它的子组件 `Avatar` 传递任何 props : ```js export default function Profile() { @@ -65,11 +68,11 @@ export default function Profile() { } ``` -You can give `Avatar` some props in two steps. +你可以分两步给 `Avatar` 一些 props。 -### Step 1: Pass props to the child component {/*step-1-pass-props-to-the-child-component*/} +### 步骤 1: 将 props 传递给子组件 {/*step-1-pass-props-to-the-child-component*/} -First, pass some props to `Avatar`. For example, let's pass two props: `person` (an object), and `size` (a number): +首先,将一些 props 传递给 `Avatar`。例如,让我们传递两个 props:`person`(一个对象)和 `size`(一个数字): ```js export default function Profile() { @@ -82,23 +85,23 @@ export default function Profile() { } ``` -> If double curly braces after `person=` confuse you, remember [they are merely an object](/learn/javascript-in-jsx-with-curly-braces#using-double-curlies-css-and-other-objects-in-jsx) inside the JSX curlies. +> 如果 `person=` 后面的双花括号让你感到困惑,请记住,在 JSX 花括号中,[它们只是一个对象](/learn/javascript-in-jsx-with-curly-braces#using-double-curlies-css-and-other-objects-in-jsx)。 -Now you can read these props inside the `Avatar` component. +现在,你可以在 `Avatar` 组件中读取这些 props 了。 -### Step 2: Read props inside the child component {/*step-2-read-props-inside-the-child-component*/} +### 步骤 2: 在子组件中读取 props {/*step-2-read-props-inside-the-child-component*/} -You can read these props by listing their names `person, size` separated by the commas inside `({` and `})` directly after `function Avatar`. This lets you use them inside the `Avatar` code, like you would with a variable. +你可以通过在 `function Avatar` 之后直接列出它们的名字 `person, size` 来读取这些 props。这些 props 在 `({` 和 `})` 之间,并由逗号分隔。这样,你可以在 `Avatar` 的代码中使用它们,就像使用变量一样。 ```js function Avatar({ person, size }) { - // person and size are available here + // 在这里 person 和 size 是可访问的 } ``` -Add some logic to `Avatar` that uses the `person` and `size` props for rendering, and you're done. +向使用 `person` 和 `size` props 渲染的 `Avatar` 添加一些逻辑,你就完成了。 -Now you can configure `Avatar` to render in many different ways with different props. Try tweaking the values! +现在你可以配置 `Avatar` ,通过不同的 props,使它能以多种不同的方式进行渲染。尝试变换值吧! @@ -164,9 +167,9 @@ body { min-height: 120px; } -Props let you think about parent and child components independently. For example, you can change the `person` or the `size` props inside `Profile` without having to think about how `Avatar` uses them. Similarly, you can change how the `Avatar` uses these props, without looking at the `Profile`. +Props 使你独立思考父组件和子组件。 例如,你可以改变 `Profile` 中的 `person` 或 `size` props,而无需考虑 `Avatar` 如何使用它们。 同样,你可以改变 `Avatar` 使用这些 props 的方式,不必考虑 `Profile`。 -You can think of props like "knobs" that you can adjust. They serve the same role as arguments serve for functions—in fact, props _are_ the only argument to your component! React component functions accept a single argument, a `props` object: +你可以将 props 想象成可以调整的“旋钮”。它们的作用与函数的参数相同 —— 事实上,props _正是_ 组件的唯一参数! React 组件函数接受一个参数,一个 `props` 对象: ```js function Avatar(props) { @@ -176,11 +179,11 @@ function Avatar(props) { } ``` -Usually you don't need the whole `props` object itself, so you destructure it into individual props. +通常你不需要整个 `props` 对象,所以可以将它解构为单独的 props。 -**Don't miss the pair of `{` and `}` curlies** inside of `(` and `)` when declaring props: +在声明 props 时, **不要忘记 `(` 和 `)` 之间的一对花括号 `{` 和 `}`** : ```js function Avatar({ person, size }) { @@ -188,7 +191,7 @@ function Avatar({ person, size }) { } ``` -This syntax is called ["destructuring"](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter) and is equivalent to reading properties from a function parameter: +这种语法被称为 [“解构”](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter),等价于于从函数参数中读取属性: ```js function Avatar(props) { @@ -200,9 +203,9 @@ function Avatar(props) { -## Specifying a default value for a prop {/*specifying-a-default-value-for-a-prop*/} +## 给 prop 指定一个默认值 {/*specifying-a-default-value-for-a-prop*/} -If you want to give a prop a default value to fall back on when no value is specified, you can do it with the destructuring by putting `=` and the default value right after the parameter: +如果你想在没有指定值的情况下给 prop 一个默认值,你可以通过在参数后面写 `=` 和默认值来进行解构: ```js function Avatar({ person, size = 100 }) { @@ -210,13 +213,13 @@ function Avatar({ person, size = 100 }) { } ``` -Now, if `` is rendered with no `size` prop, the `size` will be set to `100`. +现在, 如果 `` 渲染时没有 `size` prop, `size` 将被赋值为 `100`。 -The default value is only used if the `size` prop is missing or if you pass `size={undefined}`. But if you pass `size={null}` or `size={0}`, the default value will **not** be used. +默认值仅在缺少 `size` prop 或 `size={undefined}` 时生效。 但是如果你传递了 `size={null}` 或 `size={0}`,默认值将 **不** 被使用。 -## Forwarding props with the JSX spread syntax {/*forwarding-props-with-the-jsx-spread-syntax*/} +## 使用 JSX 展开语法传递 props {/*forwarding-props-with-the-jsx-spread-syntax*/} -Sometimes, passing props gets very repetitive: +有时候,传递 props 会变得非常重复: ```js function Profile({ person, size, isSepia, thickBorder }) { @@ -233,7 +236,7 @@ function Profile({ person, size, isSepia, thickBorder }) { } ``` -There's nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how this `Profile` does with `Avatar`. Because they don't use any of their props directly, it can make sense to use a more concise "spread" syntax: +重复代码没有错(它可以更清晰)。但有时你可能会重视简洁。一些组件将它们所有的 props 转发给子组件,正如 `Profile` 转给 `Avatar` 那样。因为它们不直接使用它们任何 props,所以使用更简洁的“展开”语法是有意义的: ```js function Profile(props) { @@ -245,13 +248,13 @@ function Profile(props) { } ``` -This forwards all of `Profile`'s props to the `Avatar` without listing each of their names. +这会将 `Profile` 的所有 props 转发到 `Avatar`,而不列出每个名字。 -**Use spread syntax with restraint.** If you're using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next! +**请克制地使用展开语法。** 如果你在所有其他组件中都使用它,那就有问题了。 通常,它表示你应该拆分组件,并将子组件作为 JSX 传递。 接下来会详细介绍! -## Passing JSX as children {/*passing-jsx-as-children*/} +## 将 JSX 作为子组件传递 {/*passing-jsx-as-children*/} -It is common to nest built-in browser tags: +嵌套浏览器内置标签是很常见的: ```js
@@ -259,7 +262,7 @@ It is common to nest built-in browser tags:
``` -Sometimes you'll want to nest your own components the same way: +有时你会希望以相同的方式嵌套自己的组件: ```js @@ -267,7 +270,7 @@ Sometimes you'll want to nest your own components the same way: ``` -When you nest content inside a JSX tag, the parent component will receive that content in a prop called `children`. For example, the `Card` component below will receive a `children` prop set to `` and render it in a wrapper div: +当您将内容嵌套在 JSX 标签中时,父组件将在名为 `children` 的 prop 中接收到该内容。例如,下面的 `Card` 组件将接收一个被设为 `` 的 `children` prop 并将其包裹在 div 中渲染: @@ -343,17 +346,16 @@ export function getImageUrl(person, size = 's') { -Try replacing the `` inside `` with some text to see how the `Card` component can wrap any nested content. It doesn't need to "know" what's being rendered inside of it. You will see this flexible pattern in many places. - -You can think of a component with a `children` prop as having a "hole" that can be "filled in" by its parent components with arbitrary JSX. You will often use the `children` prop for visual wrappers: panels, grids, and so on. +尝试用一些文本替换 `` 中的 ``,看看 `Card` 组件如何包裹任意嵌套内容。它不必“知道”其中渲染的内容。你会在很多地方看到这种灵活的模式。 +您可以将带有 `children` prop 的组件看作有一个“洞”,可以由其父组件使用任意 JSX 来“填充”。你会经常使用 `children` prop 来进行视觉包装:面板、网格等等。 -## How props change over time {/*how-props-change-over-time*/} +## Props 如何随时间变化 {/*how-props-change-over-time*/} -The `Clock` component below receives two props from its parent component: `color` and `time`. (The parent component's code is omitted because it uses [state](/learn/state-a-components-memory), which we won't dive into just yet.) +下面的 `Clock` 组件从其父组件接收两个 props:`color` 和 `time`。(父组件的代码被省略,因为它使用 [state](/learn/state-a-components-memory),我们暂时不会深入研究。) -Try changing the color in the select box below: +尝试在下面的选择框中更改颜色: @@ -388,11 +390,11 @@ export default function App() { return (

- Pick a color:{' '} + 选择一个颜色:{' '}

@@ -403,21 +405,21 @@ export default function App() { -This example illustrates that **a component may receive different props over time.** Props are not always static! Here, the `time` prop changes every second, and the `color` prop changes when you select another color. Props reflect a component's data at any point in time, rather than only in the beginning. +这个例子说明,**一个组件可能会随着时间的推移收到不同的 props。** Props 并不总是静态的!在这里,`time` prop 每秒都在变化。当你选择另一种颜色时,`color` prop 也改变了。Props 反映了组件在任何时间点的数据,并不仅仅是在开始时。 -However, props are [immutable](https://en.wikipedia.org/wiki/Immutable_object)—a term from computer science meaning "unchangeable". When a component needs to change its props (for example, in response to a user interaction or new data), it will have to "ask" its parent component to pass it _different props_—a new object! Its old props will then be cast aside, and eventually the JavaScript engine will reclaim the memory taken by them. +然而,props 是 [不可变的](https://en.wikipedia.org/wiki/Immutable_object)(一个计算机科学术语,意思是“不可改变”)。当一个组件需要改变它的 props(例如,响应用户交互或新数据)时,它不得不“请求”它的父组件传递 _不同的 props_ —— 一个新对象!它的旧 props 将被丢弃,最终 JavaScript 引擎将回收它们占用的内存。 -**Don't try to "change props".** When you need to respond to the user input (like changing the selected color), you will need to "set state", which you can learn about in [State: A Component's Memory.](/learn/state-a-components-memory) +**不要尝试“更改 props”。** 当你需要响应用户输入(例如更改所选颜色)时,你可以“设置 state”,你可以在 [State: 一个组件的内存](/learn/state-a-components-memory) 中继续了解。 -* To pass props, add them to the JSX, just like you would with HTML attributes. -* To read props, use the `function Avatar({ person, size })` destructuring syntax. -* You can specify a default value like `size = 100`, which is used for missing and `undefined` props. -* You can forward all props with `` JSX spread syntax, but don't overuse it! -* Nested JSX like `` will appear as `Card` component's `children` prop. -* Props are read-only snapshots in time: every render receives a new version of props. -* You can't change props. When you need interactivity, you'll need to set state. +* 要传递 props,请将它们添加到 JSX,就像使用 HTML 属性一样。 +* 要读取 props,请使用 `function Avatar({ person, size })` 解构语法。 +* 你可以指定一个默认值,如 `size = 100`,用于缺少值或值为 `undefined` 的 props 。 +* 你可以使用 `` JSX 展开语法转发所有 props,但不要过度使用它! +* 像 `` 这样的嵌套 JSX,将被视为 `Card` 组件的 `children` prop。 +* Props 是只读的时间快照:每次渲染都会收到新版本的 props。 +* 你不能改变 props。当你需要交互性时,你可以设置 state。 @@ -425,9 +427,9 @@ However, props are [immutable](https://en.wikipedia.org/wiki/Immutable_object) -#### Extract a component {/*extract-a-component*/} +#### 提取一个组件 {/*extract-a-component*/} -This `Gallery` component contains some very similar markup for two profiles. Extract a `Profile` component out of it to reduce the duplication. You'll need to choose what props to pass to it. +这个 `Gallery` 组件包含两份个人资料,其中有一些非常相似的标记。从中提取一个 `Profile` 组件以减少重复。你需要选择要传递哪些 props。 @@ -520,15 +522,15 @@ li { margin: 5px; } -Start by extracting the markup for one of the scientists. Then find the pieces that don't match it in the second example, and make them configurable by props. +首先提取其中一位科学家的标记。然后在第二个例子中找到不匹配的部分,用 props 配置它们。 -In this solution, the `Profile` component accepts multiple props: `imageId` (a string), `name` (a string), `profession` (a string), `awards` (an array of strings), `discovery` (a string), and `imageSize` (a number). +在这个解决方案中,`Profile` 组件接受多个 props:`imageId`(字符串)、`name`(字符串)、`profession`(字符串)、`awards`(字符串数组)、`discovery`(字符串)和 `imageSize`(数字)。 -Note that the `imageSize` prop has a default value, which is why we don't pass it to the component. +请注意,`imageSize` prop 有一个默认值,这就是为什么我们不将它传递给组件。 @@ -626,9 +628,9 @@ li { margin: 5px; } -Note how you don't need a separate `awardCount` prop if `awards` is an array. Then you can use `awards.length` to count the number of awards. Remember that props can take any values, and that includes arrays too! +请注意,如果 `awards` 是一个数组,则不需要单独的 `awardCount` prop。 你可以用 `awards.length` 来统计奖励的数量。请记住,props 可以接受任何值,也包括数组! -Another solution, which is more similar to the earlier examples on this page, is to group all information about a person in a single object, and pass that object as one prop: +另一种解决方案与本页前面的示例更相似,是将一个人的所有信息组合到一个对象中,并将该对象作为一个 prop 传递: @@ -723,15 +725,15 @@ li { margin: 5px; } -Although the syntax looks slightly different because you're describing properties of a JavaScript object rather than a collection of JSX attributes, these examples are mostly equivalent, and you can pick either approach. +尽管因为在你描述组件特性时用的是 JavaScript 对象而非 JSX 的属性,使得语法看起来略有不同,但这些示例大多都是等效的,你可以选择任意一种方法 -#### Adjust the image size based on a prop {/*adjust-the-image-size-based-on-a-prop*/} +#### 根据 props 调整图像大小 {/*adjust-the-image-size-based-on-a-prop*/} -In this example, `Avatar` receives a numeric `size` prop which determines the `` width and height. The `size` prop is set to `40` in this example. However, if you open the image in a new tab, you'll notice that the image itself is larger (`160` pixels). The real image size is determined by which thumbnail size you're requesting. +在这个例子中,`Avatar` 接收一个数字 `size` prop,它决定了 `` 的宽度和高度。在此示例中,`size` prop 设为 `40`。但是,如果你在新选项卡中打开图像,你会注意到图像本身更大(`160` 像素)。实际图像大小由你请求的缩略图大小决定。 -Change the `Avatar` component to request the closest image size based on the `size` prop. Specifically, if the `size` is less than `90`, pass `'s'` ("small") rather than `'b'` ("big") to the `getImageUrl` function. Verify that your changes work by rendering avatars with different values of the `size` prop and opening images in a new tab. +更改 `Avatar` 组件,根据 `size` prop 请求最接近的图像尺寸。具体来说,如果 `size` 小于 `90`,则将 `'s'`(“small”)而不是 `'b'`(“big”)传给 `getImageUrl` 函数。通过渲染不同 `size` prop 值的头像并在新选项卡中打开图像,来验证你的更改是否有效。 @@ -782,7 +784,7 @@ export function getImageUrl(person, size) { -Here is how you could go about it: +你可以这样做: @@ -844,7 +846,7 @@ export function getImageUrl(person, size) { -You could also show a sharper image for high DPI screens by taking [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) into account: +你还可以通过考虑 [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) 来为高 DPI 屏幕显示更清晰的图像: @@ -915,13 +917,13 @@ export function getImageUrl(person, size) { -Props let you encapsulate logic like this inside the `Avatar` component (and change it later if needed) so that everyone can use the `` component without thinking about how the images are requested and resized. +Props 可以让你将这样的逻辑封装在 `Avatar` 组件中(并在需要时进行更改),以便每个人都可以使用 `` 组件,而不必考虑如何请求和调整图像大小。 -#### Passing JSX in a `children` prop {/*passing-jsx-in-a-children-prop*/} +#### 在 `children` prop 中传递 JSX 代码 {/*passing-jsx-in-a-children-prop*/} -Extract a `Card` component from the markup below, and use the `children` prop to pass different JSX to it: +从下面的代码中提取一个 `Card` 组件,并使用 `children` prop 将不同的 JSX 传递给它: @@ -979,13 +981,13 @@ h1 { -Any JSX you put inside of a component's tag will be passed as the `children` prop to that component. +放入组件标签内的任何 JSX 都将作为 `children` prop 传递给该组件。 -This is how you can use the `Card` component in both places: +这是你可以在两个地方使用 `Card` 组件的方法: @@ -1047,7 +1049,7 @@ h1 { -You can also make `title` a separate prop if you want every `Card` to always have a title: +如果你希望每个 `Card` 都有一个标题,你还可以将 `title` 设为一个单独的 prop: