From a82456058622b06b22487e7f288a9a9847264408 Mon Sep 17 00:00:00 2001 From: Herbert Date: Thu, 2 Dec 2021 23:03:49 +0800 Subject: [PATCH 01/11] docs(cn): translate learn/thinking-in-react --- beta/src/pages/learn/thinking-in-react.md | 248 +++++++++++----------- 1 file changed, 126 insertions(+), 122 deletions(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index d1114cc584..8558f6b8d0 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -1,18 +1,20 @@ --- -title: Thinking in React +title: 在 React 中思考 +translators: + - HerbertHe --- -React can change how you think about the designs you look at and the apps you build. Where once you might have seen a forest, after working with React, you will appreciate the individual trees. React makes it easier to think in design systems and UI states. In this tutorial, we'll guide you through the thought process of building a searchable product data table with React. +React 可以改变你对设计和构建应用的思考。曾经你看到的可能是森林, 在与 React 工作为伴之后, 你将更享受每一颗独立的树。React 使对于设计系统和 UI 状态的思考更加容易。在本篇教程中, 我们将带你感悟使用 React 进行构建可搜索产品数据表格的心路历程。 -## Start with the mockup +## 使用模型开始 {/*start-with-the-mockup*/} -Imagine that you already have a JSON API and a mockup from a designer. +想象一下, 你早已从设计者那儿获取了一个 JSON API 和 模型。 -The JSON API returns some data that looks like this: +JSON API 返回如下面所示的一些数据: ```json [ @@ -25,25 +27,25 @@ The JSON API returns some data that looks like this: ] ``` -The mockup looks like this: +模型看起来如这样: -To implement a UI in React, you will usually follow the same five steps. +在 React 中实现 UI, 你仅需跟随下面的五步。 -## Step 1: Break the UI into a component hierarchy +## 步骤一: 将 UI 分解为组件层级结构 {/*step-1-break-the-ui-into-a-component-hierarchy*/} -Start by drawing boxes around every component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these components in their design tool. Check in with them! +开始, 绘制模型中每个组件和子组件周围的盒子并且命名它们。如果你与设计师一起工作, 他们可能早已在其设计工具中命名了这些组件。检查一下它们! -Depending on your background, you can think about splitting up a design into components in different ways: +依赖于你的背景, 你可以考虑通过不同的方式将设计分割为组件: -* **Programming**--use the same techniques for deciding if you should create a new function or object. One such technique is the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle), that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents. -* **CSS**--consider what you would make class selectors for. (However, components are a bit less granular.) -* **Design**--consider how you would organize the design's layers. +* **程序设计**--使用同样的技术决定你是否应该创建一个新的函数或者对象。这一技术即 [单一功能原理](https://en.wikipedia.org/wiki/Single_responsibility_principle), 也就是说, 一个组件理想地仅做一件事情。如果功能持续增长, 它应该被分解为更小的子组件。 +* **CSS**--考虑你将把类选择器用于何处。(然而, 组件并没有那么细的粒度。) +* **设计**--考虑你将如何组织布局的层级。 -If your JSON is well-structured, you'll often find that it naturally maps to the component structure of your UI. That's because UI and data models often have the same information architecture--that is, the same shape. Separate your UI into components, where each component matches one piece of your data model. +如果你的 JSON 结构非常棒, 将经常发现映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和数据模型常拥有相同的信息结构--即, 相同的形状。将你的 UI 分割到组件, 每个组件匹配到你数据模型的每个部分。 -There are five components on this screen: +在屏幕中展示了五个组件: @@ -51,33 +53,33 @@ There are five components on this screen: -1. `FilterableProductTable` (grey) contains the entire app. -2. `SearchBar` (blue) receives the user input. -3. `ProductTable` (lavender) displays and filters the list according to the user input. -4. `ProductCategoryRow` (green) displays a heading for each category. -5. `ProductRow` (yellow) displays a row for each product. +1. `FilterableProductTable (可过滤产品表)` (灰色) 包含完整的应用。 +2. `SearchBar (搜索条)` (蓝色) 获取用户输入。 +3. `ProductTable (产品表)` (淡紫色) 根据用户输入, 展示和过滤清单。 +4. `ProductCategoryRow (产品类别行)` (绿色) 展示每个类别的表头。 +5. `ProductRow (产品行)` (黄色) 展示每个产品的行。 -If you look at `ProductTable` (lavender), you'll see that the table header (containing the "Name" and "Price" labels) isn't its own component. This is a matter of preference, and you could go either way. For this example, it is a part of `ProductTable` because it appears inside the `ProductTable`'s list. However, if this header grows to be complex (e.g., if you add sorting), it would make sense to make this its own `ProductTableHeader` component. +如果你看向 `ProductTable (产品表)`, 你将看到表头 (包含 "Name" 和 "Price" 标签) 并不是它自己的组件。这是偏好的问题, 你可以采取任何一种方式继续。在这个例子中, 它是 `ProductTable` 的一部分, 因为它展现在 `ProductTable` 清单之中。然而, 如果这个表头变得复杂 (举个例子, 如果你添加排序), 创建它自己的 `ProductTableHeader` 组件就变得有意义了。 -Now that you've identified the components in the mockup, arrange them into a hierarchy. Components that appear within another component in the mockup should appear as a child in the hierarchy: +现在你已经在模型中辨别了组件, 将它们变为层级结构。在模型中, 组件可以展示在其它组件之中, 在层级结构中即展示如其孩子一般: -* `FilterableProductTable` - * `SearchBar` - * `ProductTable` - * `ProductCategoryRow` - * `ProductRow` +* `FilterableProductTable (可过滤产品表)` + * `SearchBar (搜索条)` + * `ProductTable (产品表)` + * `ProductCategoryRow (产品类别行)` + * `ProductRow (产品行)` -## Step 2: Build a static version in React +## 步骤二: 在 React 中构建一个静态版本 {/*step-2-build-a-static-version-in-react*/} -Now that you have your component hierarchy, it's time to implement your app. The most straightforward approach is to build a version that renders the UI from your data model without adding any interactivity... yet! It's often easier to build the static version first and then add interactivity separately. Building a static version requires a lot of typing and no thinking, but adding interactivity requires a lot of thinking and not a lot of typing. +现在你已经拥有了你自己的组件层级结构, 是时候实现你的应用程序了。最直接的办法是根据你的数据模型, 去构建一个不带任何交互的 UI 渲染代码版本... 然而! 经常是首先构建一个静态版本, 然后再带添加交互。构建一个静态版本需要写大量的代码, 不需要什么思考; 但添加交互需要大量的思考, 却不需要大量的代码。 -To build a static version of your app that renders your data model, you'll want to build [components](/learn/your-first-component) that reuse other components and pass data using [props](/learn/passing-props-to-a-component). Props are a way of passing data from parent to child. (If you're familiar with the concept of [state](/learn/state-a-components-memory), don't use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don't need it.) +构建你应用程序的静态版本渲染你的数据模型, 你将会构建 [组件](/learn/your-first-component) 并复用其它的组件, 接着使用 [props](/learn/passing-props-to-a-component) 传递数据。Props 是从父组件向子组件传递数据的一种方式。(如果你对 [状态(state)](/learn/state-a-components-memory) 章节很熟悉, 不要在静态版本中全部使用状态(state)进行构建。状态只是为交互提供的保留功能, 即数据会随着时间变化。因为这是一个静态应用程序, 所以不需要这个。) -You can either build "top down" by starting with building the components higher up in the hierarchy (like `FilterableProductTable`) or "bottom up" by working from components lower down (like `ProductRow`). In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up. +你既可以通过从层次结构更高层组件 (如 `FilterableProductTable`) 开始 “自上而下” 构建, 也可以通过从更低层级组件 (如 `ProductRow`) “自下而上” 进行构建。在简单的例子中, 自上而下构建通常更简单; 在大型项目中, 自下而上构建更简单。 @@ -195,105 +197,105 @@ td { -**Don't fret if this code example looks intimidating!** In this guide, we're focusing on concepts rather than code. Make sure to bookmark [Describing the UI](/learn/describing-the-ui) which will help you fill in the gaps and make sense of this code. +**如果示例看起来很吓人, 不要感到烦躁!** 在本篇导读中, 我们将更关注于概念而非代码。确认收藏 [描述 UI](/learn/describing-the-ui)将会帮助你填补短板、理解代码。 -After building your components, you'll have a library of reusable components that render your data model. Because this is a static app, the components will only return JSX. The component at the top of the hierarchy (`FilterableProductTable`) will take your data model as a prop. This is called _one-way data flow_ because the data flows down from the top-level component to the ones at the bottom of the tree. +在构建你的组件之后, 即拥有一个渲染数据模型的可复用组件库。因为这是一个静态应用程序, 组件仅返回 JSX。最顶层级的组件 (`FilterableProductTable`) 将接收你的数据模型, 并作为其 prop。这被称之为 _单向数据流_, 因为数据从树的顶端组件传递到下面的组件。 -At this point, you should not be using any state values. That’s for the next step! +在这部分中, 你不需要使用任何状态(state)数值, 这是下一步的内容。 -## Step 3: Find the minimal but complete representation of UI state +## 步骤三: 发现 UI 精简且完整的状态 (state) 表示 {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/} -To make the UI interactive, you need to let users change your underlying data model. You will use *state* for this. +使 UI 可交互, 你需要用户更改你潜在的数据结构。你将使用 *状态(state)* 进行实现。 -Think of state as the minimal set of changing data that your app needs to remember. The most important principle for structuring state is to keep it [DRY (Don't Repeat Yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)). Figure out the absolute minimal representation of the state your application needs and compute everything else on-demand. For example, if you're building a shopping list, you can store the items as an array in state. If you want to also display the number of items in the list, don't store the number of items as another state value--instead, read the length of your array. +将状态(state)作为你应用程序需要记住图改变数据的最小集合。组织状态(state)最重要的一条原则使保持它 [DRY(不要重复自己)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。计算出你应用程序需要的绝对精简的状态(state)表示, 按需计算其它一切。举个例子, 如果你正在构建一个购物清单, 你可将他们在状态(state)中存储为数组。如果你同时想展示清单中物品数量, 不需要将其另存为一个状态值(state value)。取而代之, 可以通过读取你数组的长度实现。 -Now think of all of the pieces of data in this example application: +现在考虑示例应用程序中每一条数据: -1. The original list of products -2. The search text the user has entered -3. The value of the checkbox -4. The filtered list of products +1. 产品原始清单 +2. 搜索用户键入的文本 +3. 复选框的值 +4. 过滤后的产品清单 -Which of these are state? Identify the ones that are not: +其中那些是状态(state)呢? 标记那些不是的: -* Does it **remain unchanged** over time? If so, it isn't state. -* Is it **passed in from a parent** via props? If so, it isn't state. -* **Can you compute it** based on existing state or props in your component? If so, it *definitely* isn't state! +* 随着时间推移 **保持不变**? 如此, 便不是状态(state)。 +* 通过属性(props) **从父组件传递**? 如此, 便不是状态(state)。 +* 是否可以基于已存在于组件中的状态(state) 或者 属性(props) **进行计算**? 如此, 它*肯定*不是状态(state)! -What's left is probably state. +剩下的可能是状态(state)。 -Let's go through them one by one again: +让我们再次一条条验证它们: -1. The original list of products is **passed in as props, so it's not state**. -2. The search text seems to be state since it changes over time and can't be computed from anything. -3. The value of the checkbox seems to be state since it changes over time and can't be computed from anything. -4. The filtered list of products **isn't state because it can be computed** by taking the original list of products and filtering it according to the search text and value of the checkbox. +1. 原始列表中的产品**作为属性传递, 所以它不是状态**。 +2. 搜索文本随着时间推移保持不变, 似乎是状态, 并不能被计算。 +3. 复选框的值随着时间推移保持不变, 似乎是状态, 并不能被计算。 +4. 过滤后列表中的产品**不是状态, 因为可以通过被原始列表中的产品, 根据搜索框文本和复选框的值进行计算**。 -This means only the search text and the value of the checkbox are state! Nicely done! +这就意味着只有搜索文本和复选框的值是状态! 非常好! -There are two types of "model" data in React: props and state. The two are very different: +在 React 中有两种 "模型" 数据: 属性(props) 和 状态(state)。这是它们的不同之处: -* [**Props** are like arguments you pass](/learn/passing-props-to-a-component) to a function. They let a parent component pass data to a child component and customize its appearance. For example, a `Form` can pass a `color` prop to a `Button`. -* [**State** is like a component’s memory.](/learn/state-a-components-memory) It lets a component keep track of some information and change it in response to interactions. For example, a `Button` might keep track of `isHovered` state. +* [**属性(Props)** 像是你传递的参数](/learn/passing-props-to-a-component) 至函数。它们使父组件传递数据给子组件, 定制它们的展示。举个例子, `Form` 可以传递 `color` 属性至 `Button`。 +* [**状态(State)** 像是组件的内存。](/learn/state-a-components-memory) 它使组件对一些信息保持追踪, 并且根据交互改变。举个例子, `Button` 可以保持对 `isHovered` 状态的追踪。 -Props and state are different, but they work together. A parent component will often keep some information in state (so that it can change it), and *pass it down* to child components as their props. It's okay if the difference still feels fuzzy on the first read. It takes a bit of practice for it to really stick! +属性和状态是不同的, 但是它们共同工作。父组件将经常在状态中保持一些信息 (以便它可以改变), 并且作为子组件的属性*向下*传递至它的子组件。如果第一次了解这其中的差别感到迷糊, 也没关系。大量练习即可牢牢记住! -## Step 4: Identify where your state should live +## 步骤四: 验证状态应该被放置于哪里 {/*step-4-identify-where-your-state-should-live*/} -After identifying your app’s minimal state data, you need to identify which component is responsible for changing this state, or *owns* the state. Remember: React uses one-way data flow, passing data down the component hierarchy from parent to child component. It may not be immediately clear which component should own what state. This can be challenging if you’re new to this concept, but you can figure it out by following these steps! +在验证你应用程序中的最小状态数据之后, 你需要验证哪个组件是通过改变状态可响应的, 或者*拥有*这个状态。记住: React 使用单向数据流, 通过组件层级结构从父组件传递数据至子组件。这可能不能立马知晓哪个组件拥有什么状态。如果你是第一次阅读此章节可能感到有挑战性, 但你可以通过下面的步骤搞定它! -For each piece of state in your application: +在你应用程序中的每一块状态: -1. Identify *every* component that renders something based on that state. -2. Find their closest common parent component--a component above them all in the hierarchy. -3. Decide where the state should live: - 1. Often, you can put the state directly into their common parent. - 2. You can also put the state into some component above their common parent. - 3. If you can't find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common parent component. +1. 验证*每一个*基于特定状态渲染的组件。 +2. 寻找它们最近并且共同的父组件——在层级结构中, 一个凌驾于它们所有组件之上的组件。 +3. 决定状态应该被放置于哪里: + 1. 通常情况下, 你可以直接放置状态于它们共同的父组件。、 + 2. 你也可以将状态放置于它们父组件上层的组件。 + 3. 如果你找不到一个有意义拥有这个状态的地方, 单独创建一个新的组件去管理这个状态, 并将它添加到它们父组件上层的某个地方。 -In the previous step, you found two pieces of state in this application: the search input text, and the value of the checkbox. In this example, they always appear together, so it is easier to think of them as a single piece of state. +在之前的步骤中, 你已在应用程序中创建了两块状态: 输入框文本和复选框的值。在这个例子中, 它们总一起展示, 将它们视为一个状态非常简单。 -Now let's run through our strategy for this state: +现在为这个状态贯彻我们的策略: -1. **Identify components that use state:** - * `ProductTable` needs to filter the product list based on that state (search text and checkbox value). - * `SearchBar` needs to display that state (search text and checkbox value). -1. **Find their common parent:** The first parent component both components share is `FilterableProductTable`. -2. **Decide where the state lives**: We'll keep the filter text and checked state values in `FilterableProductTable`. +1. **验证组件使用状态:** + * `ProductTable` 需要基于 状态(搜索文本和复选框值) 过滤产品列表。 + * `SearchBar` 需要展示状态(搜索文本和复选框值)。 +2. **寻找它们的父组件:** 它们的第一个共同父组件为 `FilterableProductTable`. +3. **决定状态放置的地方:** 我们将保持过滤文本和勾选状态值于 `FilterableProductTable`. -So the state values will live in `FilterableProductTable`. +所以状态将被放置在 `FilterableProductTable`。 -Add state to the component with the [`useState()` Hook](/reference/usestate). Hooks let you "hook into" a component's [render cycle](/learn/render-and-commit). Add two state variables at the top of `FilterableProductTable` and specify the initial state of your application: +通过 [`useState()` 钩子](/reference/usestate) 为组件添加状态。钩子使你 "勾入" 组件的 [渲染周期](/learn/render-and-commit)。在 `FilterableProductTable` 上面添加两个状态变量, 并在你的应用程序中指定初始值: ```js function FilterableProductTable({ products }) { const [filterText, setFilterText] = useState(''); - const [inStockOnly, setInStockOnly] = useState(false); + const [inStockOnly, setInStockOnly] = useState(false); ``` -Then, pass `filterText` and `inStockOnly` to `ProductTable` and `SearchBar` as props: +然后, 将 `filterText` 和 `inStockOnly` 作为属性传递至 `ProductTable` 和 `SearchBar`: ```js
- -
``` -You can start seeing how your application will behave. Edit the `filterText` initial value from `useState('')` to `useState('fruit')` in the sandbox code below. You'll see both the search input text and the table update: +你可以看见你的应用程序如何反应。在下面的沙盒代码, 通过修改`useState('')` 为 `useState('fruit')` 以编辑 `filterText` 的初始值, 你将会看到搜索输入值和表格更新: @@ -306,10 +308,10 @@ function FilterableProductTable({ products }) { return (
- - @@ -383,13 +385,13 @@ function ProductTable({ products, filterText, inStockOnly }) { function SearchBar({ filterText, inStockOnly }) { return (
-
); @@ -628,8 +628,8 @@ td { -你可以在 [添加交互](/learn/adding-interactivity) 这一章节, 学习到所有处理时间和更新状态的内容。 +你可以在 [添加交互](/learn/adding-interactivity) 这一章节, 学习到所有处理事件和更新 state 的内容。 -## 自此之后, 该往何处 {/*where-to-go-from-here*/} +## 自此该往何处 {/*where-to-go-from-here*/} -这所述的仅是一个简介, 旨在告诉你使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation), 或者 [深潜于所有的语法](/learn/describing-the-ui), 那些在教程中使用到的。 +本章只是一个概述, 旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation), 或者 [深潜于在教程中使用到的所有语法](/learn/describing-the-ui)。 From 0e5551af63acd73585e360de3e84e1f2f0a7dbe8 Mon Sep 17 00:00:00 2001 From: Herbert Date: Wed, 8 Dec 2021 11:59:57 +0800 Subject: [PATCH 03/11] docs(cn): translate learn/think-in-react --- beta/src/pages/learn/thinking-in-react.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 970b675cdc..80b5793ac3 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -10,9 +10,9 @@ React 可以改变你对可见设计和应用构建的思考。曾经你可能 -## 从模型开始 {/*start-with-the-mockup*/} +## 从 mockup 开始 {/*start-with-the-mockup*/} -想象一下, 你早已从设计者那儿得到了一个 JSON API 和模型。 +想象一下, 你早已从设计者那儿得到了一个 JSON API 和 mockup。 JSON API 返回如下的数据: @@ -27,7 +27,7 @@ JSON API 返回如下的数据: ] ``` -模型看起来像是这样: +mockup 看起来像是这样: @@ -35,7 +35,7 @@ JSON API 返回如下的数据: ## 步骤一: 将 UI 拆解为组件层级结构 {/*step-1-break-the-ui-into-a-component-hierarchy*/} -一开始, 在绘制模型中的每个组件和子组件周围绘制盒子并命名它们。如果你与设计师一起工作, 他们可能早已在其设计工具中对这些组件进行了命名。检查一下它们! +一开始, 在绘制 mockup 中的每个组件和子组件周围绘制盒子并命名它们。如果你与设计师一起工作, 他们可能早已在其设计工具中对这些组件进行了命名。检查一下它们! 取决于你的使用背景, 可以考虑通过不同的方式将设计分割为组件: @@ -43,7 +43,7 @@ JSON API 返回如下的数据: * **CSS**--思考你将把类选择器用于何处。(然而, 组件并没有那么细的粒度。) * **设计**--思考你将如何组织布局的层级。 -如果你的 JSON 结构非常棒, 经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和模型常拥有相同的信息结构--即, 相同的形状。将你的 UI 分割到组件, 每个组件匹配到模型中的每个部分。 +如果你的 JSON 结构非常棒, 经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和 mockup 常拥有相同的信息结构--即, 相同的形状。将你的 UI 分割到组件, 每个组件匹配到 mockup 中的每个部分。 在屏幕中展示了五个组件: @@ -65,7 +65,7 @@ JSON API 返回如下的数据: 看向 `ProductTable`(淡紫色), 可以看到表头 (包含 "Name" 和 "Price" 标签) 并不是独立的组件。这是个人喜好的问题, 你可以采取任何一种方式继续。在这个例子中, 它是作为 `ProductTable` 的一部分, 因为它展现在 `ProductTable` 列表之中。然而, 如果这个表头变得复杂 (举个例子, 如果添加排序), 创建独立的 `ProductTableHeader` 组件就变得有意义了。 -现在你已经在模型中辨别了组件, 并将它们转化为了层级结构。在模型中, 组件可以展示在其它组件之中, 在层级结构中如同其孩子一般: +现在你已经在 mockup 中辨别了组件, 并将它们转化为了层级结构。在 mockup 中, 组件可以展示在其它组件之中, 在层级结构中如同其孩子一般: * `FilterableProductTable` * `SearchBar` From 095b7de5fcb82f641601fdbdb5dae5db5c8ed962 Mon Sep 17 00:00:00 2001 From: Herbert Date: Wed, 8 Dec 2021 12:05:18 +0800 Subject: [PATCH 04/11] docs(cn): translate learn/think-in-react --- beta/src/pages/learn/thinking-in-react.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 80b5793ac3..f05027319d 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -1,5 +1,5 @@ --- -title: 在 React 中思考 +title: React 哲学 translators: - HerbertHe --- @@ -10,9 +10,9 @@ React 可以改变你对可见设计和应用构建的思考。曾经你可能 -## 从 mockup 开始 {/*start-with-the-mockup*/} +## 从原型开始 {/*start-with-the-mockup*/} -想象一下, 你早已从设计者那儿得到了一个 JSON API 和 mockup。 +想象一下, 你早已从设计者那儿得到了一个 JSON API 和原型。 JSON API 返回如下的数据: @@ -27,7 +27,7 @@ JSON API 返回如下的数据: ] ``` -mockup 看起来像是这样: +原型看起来像是这样: @@ -35,7 +35,7 @@ mockup 看起来像是这样: ## 步骤一: 将 UI 拆解为组件层级结构 {/*step-1-break-the-ui-into-a-component-hierarchy*/} -一开始, 在绘制 mockup 中的每个组件和子组件周围绘制盒子并命名它们。如果你与设计师一起工作, 他们可能早已在其设计工具中对这些组件进行了命名。检查一下它们! +一开始, 在绘制原型中的每个组件和子组件周围绘制盒子并命名它们。如果你与设计师一起工作, 他们可能早已在其设计工具中对这些组件进行了命名。检查一下它们! 取决于你的使用背景, 可以考虑通过不同的方式将设计分割为组件: @@ -43,7 +43,7 @@ mockup 看起来像是这样: * **CSS**--思考你将把类选择器用于何处。(然而, 组件并没有那么细的粒度。) * **设计**--思考你将如何组织布局的层级。 -如果你的 JSON 结构非常棒, 经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和 mockup 常拥有相同的信息结构--即, 相同的形状。将你的 UI 分割到组件, 每个组件匹配到 mockup 中的每个部分。 +如果你的 JSON 结构非常棒, 经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和原型常拥有相同的信息结构--即, 相同的形状。将你的 UI 分割到组件, 每个组件匹配到原型中的每个部分。 在屏幕中展示了五个组件: @@ -65,7 +65,7 @@ mockup 看起来像是这样: 看向 `ProductTable`(淡紫色), 可以看到表头 (包含 "Name" 和 "Price" 标签) 并不是独立的组件。这是个人喜好的问题, 你可以采取任何一种方式继续。在这个例子中, 它是作为 `ProductTable` 的一部分, 因为它展现在 `ProductTable` 列表之中。然而, 如果这个表头变得复杂 (举个例子, 如果添加排序), 创建独立的 `ProductTableHeader` 组件就变得有意义了。 -现在你已经在 mockup 中辨别了组件, 并将它们转化为了层级结构。在 mockup 中, 组件可以展示在其它组件之中, 在层级结构中如同其孩子一般: +现在你已经在原型中辨别了组件, 并将它们转化为了层级结构。在原型中, 组件可以展示在其它组件之中, 在层级结构中如同其孩子一般: * `FilterableProductTable` * `SearchBar` From 044b87145881e0476ff7e2dc10aba0f951259c81 Mon Sep 17 00:00:00 2001 From: Herbert Date: Wed, 8 Dec 2021 23:00:21 +0800 Subject: [PATCH 05/11] docs(cn): translate learn/thinking-in-react --- beta/src/pages/learn/thinking-in-react.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index f05027319d..937ab9842d 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -640,4 +640,4 @@ td { ## 自此该往何处 {/*where-to-go-from-here*/} -本章只是一个概述, 旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation), 或者 [深潜于在教程中使用到的所有语法](/learn/describing-the-ui)。 +本章只是一个概述, 旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation), 或者 [深入了解在教程中用到的所有语法](/learn/describing-the-ui)。 From 4e57c120ad18e96e09dd100e1bbee76483932bf1 Mon Sep 17 00:00:00 2001 From: Herbert Date: Wed, 15 Dec 2021 13:58:53 +0800 Subject: [PATCH 06/11] docs(cn): update translation --- beta/src/pages/learn/thinking-in-react.md | 96 +++++++++++------------ 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 937ab9842d..cf9e45ff55 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -6,13 +6,13 @@ translators: -React 可以改变你对可见设计和应用构建的思考。曾经你可能已见过成片的森林, 在与 React 工作为伴后, 你将更享受其中每一颗独立的树。React 使思考设计系统和 UI 状态更加容易。在本篇教程中, 我们将带你领略使用 React 进行构建可搜索产品数据表格的全过程。 +React 可以改变你对可见设计和应用构建的思考。曾经你可能已见过成片的森林,在与 React 工作为伴后,你将更享受其中每一颗独立的树。React 使思考设计系统和 UI 状态更加容易。在本篇教程中,我们将带你领略使用 React 进行构建可搜索产品数据表格的全过程。 ## 从原型开始 {/*start-with-the-mockup*/} -想象一下, 你早已从设计者那儿得到了一个 JSON API 和原型。 +想象一下,你早已从设计者那儿得到了一个 JSON API 和原型。 JSON API 返回如下的数据: @@ -31,19 +31,19 @@ JSON API 返回如下的数据: -仅需跟随下面的五步, 即可使用 React 中实现 UI。 +仅需跟随下面的五步,即可使用 React 中实现 UI。 ## 步骤一: 将 UI 拆解为组件层级结构 {/*step-1-break-the-ui-into-a-component-hierarchy*/} -一开始, 在绘制原型中的每个组件和子组件周围绘制盒子并命名它们。如果你与设计师一起工作, 他们可能早已在其设计工具中对这些组件进行了命名。检查一下它们! +一开始,在绘制原型中的每个组件和子组件周围绘制盒子并命名它们。如果你与设计师一起工作,他们可能早已在其设计工具中对这些组件进行了命名。检查一下它们! -取决于你的使用背景, 可以考虑通过不同的方式将设计分割为组件: +取决于你的使用背景,可以考虑通过不同的方式将设计分割为组件: -* **程序设计**--使用同样的技术决定你是否应该创建一个新的函数或者对象。这一技术即 [单一功能原理](https://en.wikipedia.org/wiki/Single_responsibility_principle), 也就是说, 一个组件理想得仅做一件事情。但随着功能的持续增长, 它应该被分解为更小的子组件。 -* **CSS**--思考你将把类选择器用于何处。(然而, 组件并没有那么细的粒度。) +* **程序设计**--使用同样的技术决定你是否应该创建一个新的函数或者对象。这一技术即 [单一功能原理](https://en.wikipedia.org/wiki/Single_responsibility_principle),也就是说,一个组件理想得仅做一件事情。但随着功能的持续增长,它应该被分解为更小的子组件。 +* **CSS**--思考你将把类选择器用于何处。(然而,组件并没有那么细的粒度。) * **设计**--思考你将如何组织布局的层级。 -如果你的 JSON 结构非常棒, 经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和原型常拥有相同的信息结构--即, 相同的形状。将你的 UI 分割到组件, 每个组件匹配到原型中的每个部分。 +如果你的 JSON 结构非常棒,经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和原型常拥有相同的信息结构--即,相同的形状。将你的 UI 分割到组件,每个组件匹配到原型中的每个部分。 在屏幕中展示了五个组件: @@ -55,7 +55,7 @@ JSON API 返回如下的数据: 1. `FilterableProductTable` (灰色) 包含完整的应用。 2. `SearchBar` (蓝色) 获取用户输入。 -3. `ProductTable` (淡紫色) 根据用户输入, 展示和过滤清单。 +3. `ProductTable` (淡紫色) 根据用户输入,展示和过滤清单。 4. `ProductCategoryRow` (绿色) 展示每个类别的表头。 5. `ProductRow` (黄色) 展示每个产品的行。 @@ -63,9 +63,9 @@ JSON API 返回如下的数据: -看向 `ProductTable`(淡紫色), 可以看到表头 (包含 "Name" 和 "Price" 标签) 并不是独立的组件。这是个人喜好的问题, 你可以采取任何一种方式继续。在这个例子中, 它是作为 `ProductTable` 的一部分, 因为它展现在 `ProductTable` 列表之中。然而, 如果这个表头变得复杂 (举个例子, 如果添加排序), 创建独立的 `ProductTableHeader` 组件就变得有意义了。 +看向 `ProductTable`(淡紫色),可以看到表头 (包含 "Name" 和 "Price" 标签) 并不是独立的组件。这是个人喜好的问题,你可以采取任何一种方式继续。在这个例子中,它是作为 `ProductTable` 的一部分,因为它展现在 `ProductTable` 列表之中。然而,如果这个表头变得复杂 (举个例子,如果添加排序),创建独立的 `ProductTableHeader` 组件就变得有意义了。 -现在你已经在原型中辨别了组件, 并将它们转化为了层级结构。在原型中, 组件可以展示在其它组件之中, 在层级结构中如同其孩子一般: +现在你已经在原型中辨别了组件,并将它们转化为了层级结构。在原型中,组件可以展示在其它组件之中,在层级结构中如同其孩子一般: * `FilterableProductTable` * `SearchBar` @@ -75,11 +75,11 @@ JSON API 返回如下的数据: ## 步骤二: 使用 React 中构建一个静态版本 {/*step-2-build-a-static-version-in-react*/} -现在你已经拥有了你自己的组件层级结构, 是时候实现你的应用程序了。最直接的办法是根据你的数据模型, 构建一个不带任何交互的 UI 渲染代码版本...经常是先构建一个静态版本比较简单, 然后再一个个添加交互。构建一个静态版本需要写大量的代码, 并不需要什么思考; 但添加交互需要大量的思考, 却不需要大量的代码。 +现在你已经拥有了你自己的组件层级结构,是时候实现你的应用程序了。最直接的办法是根据你的数据模型,构建一个不带任何交互的 UI 渲染代码版本...经常是先构建一个静态版本比较简单,然后再一个个添加交互。构建一个静态版本需要写大量的代码,并不需要什么思考; 但添加交互需要大量的思考,却不需要大量的代码。 -构建应用程序的静态版本来渲染你的数据模型, 将构建 [组件](/learn/your-first-component) 并复用其它的组件, 然后使用 [props](/learn/passing-props-to-a-component) 进行传递数据。Props 是从父组件向子组件传递数据的一种方式。(如果你对 [state](/learn/state-a-components-memory) 章节很熟悉, 不要在静态版本中使用 state 进行构建。state 只是为交互提供的保留功能, 即数据会随着时间变化。因为这是一个静态应用程序, 所以并不需要。) +构建应用程序的静态版本来渲染你的数据模型,将构建 [组件](/learn/your-first-component) 并复用其它的组件,然后使用 [props](/learn/passing-props-to-a-component) 进行传递数据。Props 是从父组件向子组件传递数据的一种方式。(如果你对 [state](/learn/state-a-components-memory) 章节很熟悉,不要在静态版本中使用 state 进行构建。state 只是为交互提供的保留功能,即数据会随着时间变化。因为这是一个静态应用程序,所以并不需要。) -你既可以通过从层次结构更高层组件 (如 `FilterableProductTable`) 开始 "自上而下" 构建, 也可以通过从更低层级组件 (如 `ProductRow`) "自下而上" 进行构建。在简单的例子中, 自上而下构建通常更简单; 而在大型项目中, 自下而上构建更简单。 +你既可以通过从层次结构更高层组件 (如 `FilterableProductTable`) 开始 "自上而下" 构建,也可以通过从更低层级组件 (如 `ProductRow`) "自下而上" 进行构建。在简单的例子中,自上而下构建通常更简单; 而在大型项目中,自下而上构建更简单。 @@ -197,21 +197,21 @@ td { -**如果示例看起来很吓人, 不要感到烦躁!** 在本篇指南中, 我们将更关注于概念而非代码。收藏 [描述 UI](/learn/describing-the-ui) 的内容, 将会帮助你填补短板、理解代码。 +**如果示例看起来很吓人,不要感到烦躁!* 在本篇指南中,我们将更关注于概念而非代码。收藏 [描述 UI](/learn/describing-the-ui) 的内容,将会帮助你填补短板、理解代码。 -在构建你的组件之后, 即拥有一个渲染数据模型的可复用组件库。因为这是一个静态应用程序, 组件仅返回 JSX。最顶层组件 (`FilterableProductTable`) 将接收你的数据模型作为其 prop。这被称之为 _单向数据流_, 因为数据从树的顶层组件传递到下面的组件。 +在构建你的组件之后,即拥有一个渲染数据模型的可复用组件库。因为这是一个静态应用程序,组件仅返回 JSX。最顶层组件 (`FilterableProductTable`) 将接收你的数据模型作为其 prop。这被称之为 _单向数据流_,因为数据从树的顶层组件传递到下面的组件。 -在这部分中, 你不需要使用任何 state, 这是下一步的内容! +在这部分中,你不需要使用任何 state,这是下一步的内容! ## 步骤三: 发现 UI 精简且完整的 state 表示 {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/} -为了使 UI 可交互, 你需要用户更改潜在的数据结构。你将可以使用 *state* 进行实现。 +为了使 UI 可交互,你需要用户更改潜在的数据结构。你将可以使用 *state* 进行实现。 -考虑将 state 作为应用程序需要记住改变数据的最小集合。组织 state 最重要的一条原则是保持它 [DRY(不要自我重复)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。计算出你应用程序需要的绝对精简 state 表示, 按需计算其它一切。举个例子, 如果你正在构建一个购物列表, 你可将他们在 state 中存储为数组。如果你同时想展示列表中物品数量, 不需要将其另存为一个新的 state。取而代之, 可以通过读取你数组的长度来实现。 +考虑将 state 作为应用程序需要记住改变数据的最小集合。组织 state 最重要的一条原则是保持它 [DRY(不要自我重复)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。计算出你应用程序需要的绝对精简 state 表示,按需计算其它一切。举个例子,如果你正在构建一个购物列表,你可将他们在 state 中存储为数组。如果你同时想展示列表中物品数量,不需要将其另存为一个新的 state。取而代之,可以通过读取你数组的长度来实现。 现在考虑示例应用程序中的每一条数据: @@ -220,48 +220,48 @@ td { 3. 复选框的值 4. 过滤后的产品列表 -其中哪些是 state 呢? 标记出那些不是的: +其中哪些是 state 呢? 标记出那些不是的: -* 随着时间推移 **保持不变**? 如此, 便不是 state。 -* 通过 props **从父组件传递**? 如此, 便不是 state。 -* 是否可以基于已存在于组件中的 state 或者 props **进行计算**? 如此, 它*肯定*不是state! +* 随着时间推移 **保持不变**? 如此,便不是 state。 +* 通过 props **从父组件传递**? 如此,便不是 state。 +* 是否可以基于已存在于组件中的 state 或者 props **进行计算**? 如此,它*肯定*不是state! 剩下的可能是 state。 让我们再次一条条验证它们: -1. 原始列表中的产品**作为 props 传递, 所以它不是 state**。 -2. 搜索文本随着时间推移保持不变, 似乎是 state, 并不能被计算。 -3. 复选框的值随着时间推移保持不变, 似乎是 state, 并不能被计算。 -4. 过滤后列表中的产品**不是 state, 因为可以通过被原始列表中的产品, 根据搜索框文本和复选框的值进行计算**。 +1. 原始列表中的产品**作为 props 传递,所以它不是 state**。 +2. 搜索文本随着时间推移保持不变,似乎是 state,并不能被计算。 +3. 复选框的值随着时间推移保持不变,似乎是 state,并不能被计算。 +4. 过滤后列表中的产品**不是 state,因为可以通过被原始列表中的产品,根据搜索框文本和复选框的值进行计算**。 -这就意味着只有搜索文本和复选框的值是 state! 非常好! +这就意味着只有搜索文本和复选框的值是 state!非常好! 在 React 中有两种 "模型" 数据: props 和 state。下面是它们的不同之处: -* [**Props** 像是你传递的参数](/learn/passing-props-to-a-component) 至函数。它们使父组件可以传递数据给子组件, 定制它们的展示。举个例子, `Form` 可以传递 `color` prop 至 `Button`。 -* [**State** 像是组件的内存](/learn/state-a-components-memory)。它使组件可以对一些信息保持追踪, 并根据交互来改变。举个例子, `Button` 可以保持对 `isHovered` state 的追踪。 +* [**Props** 像是你传递的参数](/learn/passing-props-to-a-component) 至函数。它们使父组件可以传递数据给子组件,定制它们的展示。举个例子,`Form` 可以传递 `color` prop 至 `Button`。 +* [**State** 像是组件的内存](/learn/state-a-components-memory)。它使组件可以对一些信息保持追踪,并根据交互来改变。举个例子,`Button` 可以保持对 `isHovered` state 的追踪。 -Props 和 state 是不同的, 但它们可以共同工作。父组件将经常在 state 中放置一些信息(以便它可以改变), 并且作为子组件的属性*向下*传递至它的子组件。如果第一次了解这其中的差别感到迷惑, 也没关系。通过大量练习即可牢牢记住! +Props 和 state 是不同的,但它们可以共同工作。父组件将经常在 state 中放置一些信息(以便它可以改变),并且作为子组件的属性*向下*传递至它的子组件。如果第一次了解这其中的差别感到迷惑,也没关系。通过大量练习即可牢牢记住! ## 步骤四: 验证 state 应该被放置在哪里 {/*step-4-identify-where-your-state-should-live*/} -在验证你应用程序中的最小 state 数据之后, 你需要验证哪个组件是通过改变 state 实现可响应的, 或者*拥有*这个 state。记住: React 使用单向数据流, 通过组件层级结构从父组件传递数据至子组件。这可能不能立马知晓哪个组件拥有什么 state。如果你是第一次阅读此章节可能会感到有挑战性, 但可以通过下面的步骤搞定它! +在验证你应用程序中的最小 state 数据之后,你需要验证哪个组件是通过改变 state 实现可响应的,或者*拥有*这个 state。记住: React 使用单向数据流,通过组件层级结构从父组件传递数据至子组件。这可能不能立马知晓哪个组件拥有什么 state。如果你是第一次阅读此章节可能会感到有挑战性,但可以通过下面的步骤搞定它! 为你应用程序中的每一个 state: 1. 验证*每一个*基于特定 state 渲染的组件。 -2. 寻找它们最近并且共同的父组件——在层级结构中, 一个凌驾于它们所有组件之上的组件。 +2. 寻找它们最近并且共同的父组件——在层级结构中,一个凌驾于它们所有组件之上的组件。 3. 决定 state 应该被放置于哪里: - 1. 通常情况下, 你可以直接放置 state 于它们共同的父组件。 + 1. 通常情况下,你可以直接放置 state 于它们共同的父组件。 2. 你也可以将 state 放置于它们父组件上层的组件。 - 3. 如果你找不到一个有意义拥有这个 state 的地方, 单独创建一个新的组件去管理这个 state, 并将它添加到它们父组件上层的某个地方。 + 3. 如果你找不到一个有意义拥有这个 state 的地方,单独创建一个新的组件去管理这个 state,并将它添加到它们父组件上层的某个地方。 -在之前的步骤中, 你已在应用程序中创建了两个 state: 输入框文本和复选框的值。在这个例子中, 它们总在一起展示, 将其视为一个 state 非常简单。 +在之前的步骤中,你已在应用程序中创建了两个 state: 输入框文本和复选框的值。在这个例子中,它们总在一起展示,将其视为一个 state 非常简单。 现在为这个 state 贯彻我们的策略: @@ -273,7 +273,7 @@ Props 和 state 是不同的, 但它们可以共同工作。父组件将经常 所以 state 将被放置在 `FilterableProductTable`。 -通过 [`useState()` 钩子](/reference/usestate) 为组件添加 state。钩子使你 "勾入" 组件的 [渲染周期](/learn/render-and-commit)。在 `FilterableProductTable` 上面添加两个 state 变量, 并在你的应用程序中指定初始值: +通过 [`useState()` 钩子](/reference/usestate) 为组件添加 state。钩子使你 "勾入" 组件的 [渲染周期](/learn/render-and-commit)。在 `FilterableProductTable` 上面添加两个 state 变量,并在你的应用程序中指定初始值: ```js function FilterableProductTable({ products }) { @@ -281,7 +281,7 @@ function FilterableProductTable({ products }) { const [inStockOnly, setInStockOnly] = useState(false); ``` -然后, 将 `filterText` 和 `inStockOnly` 作为属性传递至 `ProductTable` 和 `SearchBar`: +然后, `filterText` 和 `inStockOnly` 作为属性传递至 `ProductTable` 和 `SearchBar`: ```js
@@ -295,7 +295,7 @@ function FilterableProductTable({ products }) {
``` -你可以看见应用程序如何反应。在下面的沙盒代码, 通过修改`useState('')` 为 `useState('fruit')` 以编辑 `filterText` 的初始值, 你将会看到搜索输入值和表格更新: +你可以看见应用程序如何反应。在下面的沙盒代码,过修改`useState('')` 为 `useState('fruit')` 以编辑 `filterText` 的初始值,将会看到搜索输入值和表格更新: @@ -437,8 +437,8 @@ td { -在上面的沙盒中, `ProductTable` 和 `SearchBar` 读取 `filterText` 和 `inStockOnly` props 以渲染表格、输入、复选框。 -举个例子, 这里展示了 `SearchBar` 如何填充输入的值: +在上面的沙盒中,`ProductTable` 和 `SearchBar` 读取 `filterText` 和 `inStockOnly` props 以渲染表格、输入、复选框。 +举个例子,里展示了 `SearchBar` 如何填充输入的值: ```js {1,6} function SearchBar({ filterText, inStockOnly }) { @@ -451,15 +451,15 @@ function SearchBar({ filterText, inStockOnly }) { ``` -参照 [管理 State](/learn/managing-state) 去深度了解 React 如何使用 state , 又如何在你的应用程序中组织。 +参照 [管理 State](/learn/managing-state) 去深度了解 React 如何使用 state ,如何在你的应用程序中组织。 ## 步骤五: 添加反向数据流 {/*step-5-add-inverse-data-flow*/} -目前你的应用程序可以带着 props 和 state 随着层级结构进行正确渲染。但是根据用户的输入改变 state, 你需要通过其它的方式支持数据流: 深层结构的表单组件需要在 `FilterableProductTable` 中更新 state 。 +目前你的应用程序可以带着 props 和 state 随着层级结构进行正确渲染。但是根据用户的输入改变 state,需要通过其它的方式支持数据流: 深层结构的表单组件需要在 `FilterableProductTable` 中更新 state。 -React 使数据流显式展示, 但是与双向数据绑定相比, 它需要更多的输入。如果你尝试在上述的例子中输入或者勾选复选框, 会发现 React 忽视了你的输入。这点是有意为之的。通过 ``, 你已经设置了 `input` 的 `value` 属性, 并使之恒等于从 `FilterableProductTable` 传递的 `filterText` state。只要 `filterText` state 不设置, 输入的值就不会改变。 +React 使数据流显式展示,是与双向数据绑定相比,需要更多的输入。如果你尝试在上述的例子中输入或者勾选复选框,发现 React 忽视了你的输入。这点是有意为之的。通过 ``,已经设置了 `input` 的 `value` 属性,使之恒等于从 `FilterableProductTable` 传递的 `filterText` state。只要 `filterText` state 不设置,入的值就不会改变。 -当用户更改表单输入时, state 将更新以反映这些更改。state 由 `FilterableProductTable` 所拥有, 所以只有它可以调用 `setFilterText` 和 `setInStockOnly`。使 `SearchBar` 更新 `FilterableProductTable` 的 state, 你需要将这些函数传递到 `SearchBar`: +当用户更改表单输入时, state 将更新以反映这些更改。state 由 `FilterableProductTable` 所拥有,以只有它可以调用 `setFilterText` 和 `setInStockOnly`。使 `SearchBar` 更新 `FilterableProductTable` 的 state,需要将这些函数传递到 `SearchBar`: ```js {2,3,10,11} @@ -476,7 +476,7 @@ function FilterableProductTable({ products }) { onInStockOnlyChange={setInStockOnly} /> ``` -在 `SearchBar` 中, 将添加一个 `onChange` 事件处理器, 并使用其设置父组件的 state: +在 `SearchBar` 中,添加一个 `onChange` 事件处理器,使用其设置父组件的 state: ```js {5} -你可以在 [添加交互](/learn/adding-interactivity) 这一章节, 学习到所有处理事件和更新 state 的内容。 +你可以在 [添加交互](/learn/adding-interactivity) 这一章节,学习到所有处理事件和更新 state 的内容。 ## 自此该往何处 {/*where-to-go-from-here*/} -本章只是一个概述, 旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation), 或者 [深入了解在教程中用到的所有语法](/learn/describing-the-ui)。 +本章只是一个概述,旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation),或者 [深入了解在教程中用到的所有语法](/learn/describing-the-ui)。 From d9189edd0b5361f9b17285b7060a35c7a0648e2e Mon Sep 17 00:00:00 2001 From: KnowsCount Date: Sat, 22 Jan 2022 14:07:16 +0800 Subject: [PATCH 07/11] fix: fixing a few errors --- beta/src/pages/learn/thinking-in-react.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index cf9e45ff55..79615190cb 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -2,6 +2,7 @@ title: React 哲学 translators: - HerbertHe + - KnowsCount --- @@ -79,7 +80,7 @@ JSON API 返回如下的数据: 构建应用程序的静态版本来渲染你的数据模型,将构建 [组件](/learn/your-first-component) 并复用其它的组件,然后使用 [props](/learn/passing-props-to-a-component) 进行传递数据。Props 是从父组件向子组件传递数据的一种方式。(如果你对 [state](/learn/state-a-components-memory) 章节很熟悉,不要在静态版本中使用 state 进行构建。state 只是为交互提供的保留功能,即数据会随着时间变化。因为这是一个静态应用程序,所以并不需要。) -你既可以通过从层次结构更高层组件 (如 `FilterableProductTable`) 开始 "自上而下" 构建,也可以通过从更低层级组件 (如 `ProductRow`) "自下而上" 进行构建。在简单的例子中,自上而下构建通常更简单; 而在大型项目中,自下而上构建更简单。 +你既可以通过从层次结构更高层组件 (如 `FilterableProductTable`) 开始 "自上而下" 构建,也可以通过从更低层级组件 (如 `ProductRow`) "自下而上" 进行构建。在简单的例子中,自上而下构建通常更简单;而在大型项目中,自下而上构建更简单。 @@ -197,7 +198,7 @@ td { -**如果示例看起来很吓人,不要感到烦躁!* 在本篇指南中,我们将更关注于概念而非代码。收藏 [描述 UI](/learn/describing-the-ui) 的内容,将会帮助你填补短板、理解代码。 +**如果示例看起来很吓人,不要感到烦躁!**在本篇指南中,我们将更关注于概念而非代码。收藏 [描述 UI](/learn/describing-the-ui) 的内容,将会帮助你填补短板、理解代码。 在构建你的组件之后,即拥有一个渲染数据模型的可复用组件库。因为这是一个静态应用程序,组件仅返回 JSX。最顶层组件 (`FilterableProductTable`) 将接收你的数据模型作为其 prop。这被称之为 _单向数据流_,因为数据从树的顶层组件传递到下面的组件。 @@ -230,10 +231,10 @@ td { 让我们再次一条条验证它们: -1. 原始列表中的产品**作为 props 传递,所以它不是 state**。 +1. 原始列表中的产品 **被作为 props 传递,所以不是 state**。 2. 搜索文本随着时间推移保持不变,似乎是 state,并不能被计算。 3. 复选框的值随着时间推移保持不变,似乎是 state,并不能被计算。 -4. 过滤后列表中的产品**不是 state,因为可以通过被原始列表中的产品,根据搜索框文本和复选框的值进行计算**。 +4. 过滤后列表中的产品 **不是 state,因为可以通过被原始列表中的产品,根据搜索框文本和复选框的值进行计算**。 这就意味着只有搜索文本和复选框的值是 state!非常好! @@ -250,7 +251,7 @@ Props 和 state 是不同的,但它们可以共同工作。父组件将经常 ## 步骤四: 验证 state 应该被放置在哪里 {/*step-4-identify-where-your-state-should-live*/} -在验证你应用程序中的最小 state 数据之后,你需要验证哪个组件是通过改变 state 实现可响应的,或者*拥有*这个 state。记住: React 使用单向数据流,通过组件层级结构从父组件传递数据至子组件。这可能不能立马知晓哪个组件拥有什么 state。如果你是第一次阅读此章节可能会感到有挑战性,但可以通过下面的步骤搞定它! +在验证你应用程序中的最小 state 数据之后,你需要验证哪个组件是通过改变 state 实现可响应的,或者 *拥有* 这个 state。记住:React 使用单向数据流,通过组件层级结构从父组件传递数据至子组件。这可能不能立马知晓哪个组件拥有什么 state。如果你是第一次阅读此章节可能会感到有挑战性,但可以通过下面的步骤搞定它! 为你应用程序中的每一个 state: From 37dc86f7346d07fad6ed742fa748c205767f8199 Mon Sep 17 00:00:00 2001 From: QiChang Li Date: Fri, 27 May 2022 10:56:09 +0800 Subject: [PATCH 08/11] Apply suggestions from code review Co-authored-by: mophia --- beta/src/pages/learn/thinking-in-react.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 7ff5e8a10b..68c07fc252 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -7,7 +7,7 @@ translators: -React 可以改变你对可见设计和应用构建的思考。曾经你可能已见过成片的森林,在与 React 工作为伴后,你将更享受其中每一颗独立的树。React 使思考设计系统和 UI 状态更加容易。在本篇教程中,我们将带你领略使用 React 进行构建可搜索产品数据表格的全过程。 +React 可以改变你对可见设计和应用构建的思考。打个比方,或许你对成片的森林赞不绝口,使用了 React 之后,你赞叹于其中的每一棵树都光彩夺目。使用 React 使得设计用户视图、管理系统状态变得更容易。在本篇教程中,我们将带你领略使用 React 构建可搜索产品数据表格的全过程。 @@ -46,7 +46,7 @@ JSON API 返回如下的数据: 如果你的 JSON 结构非常棒,经常会发现其映射到 UI 中的组件结构是一件自然而然的事情。那是因为 UI 和原型常拥有相同的信息结构--即,相同的形状。将你的 UI 分割到组件,每个组件匹配到原型中的每个部分。 -在屏幕中展示了五个组件: +以下展示了五个组件: @@ -74,7 +74,7 @@ JSON API 返回如下的数据: * `ProductCategoryRow` * `ProductRow` -## 步骤二: 使用 React 中构建一个静态版本 {/*step-2-build-a-static-version-in-react*/} +## 步骤二: 使用 React 构建一个静态版本 {/*step-2-build-a-static-version-in-react*/} 现在你已经拥有了你自己的组件层级结构,是时候实现你的应用程序了。最直接的办法是根据你的数据模型,构建一个不带任何交互的 UI 渲染代码版本...经常是先构建一个静态版本比较简单,然后再一个个添加交互。构建一个静态版本需要写大量的代码,并不需要什么思考; 但添加交互需要大量的思考,却不需要大量的代码。 @@ -251,7 +251,7 @@ Props 和 state 是不同的,但它们可以共同工作。父组件将经常 ## 步骤四: 验证 state 应该被放置在哪里 {/*step-4-identify-where-your-state-should-live*/} -在验证你应用程序中的最小 state 数据之后,你需要验证哪个组件是通过改变 state 实现可响应的,或者 *拥有* 这个 state。记住:React 使用单向数据流,通过组件层级结构从父组件传递数据至子组件。这可能不能立马知晓哪个组件拥有什么 state。如果你是第一次阅读此章节可能会感到有挑战性,但可以通过下面的步骤搞定它! +在验证你应用程序中的最小 state 数据之后,你需要验证哪个组件是通过改变 state 实现可响应的,或者 *拥有* 这个 state。记住:React 使用单向数据流,通过组件层级结构从父组件传递数据至子组件。要搞清楚哪个组件拥有哪个 state。如果你是第一次阅读此章节,可能会很有挑战,但可以通过下面的步骤搞定它! 为你应用程序中的每一个 state: @@ -274,7 +274,7 @@ Props 和 state 是不同的,但它们可以共同工作。父组件将经常 所以 state 将被放置在 `FilterableProductTable`。 -Add state to the component with the [`useState()` Hook](/apis/usestate). Hooks let you "hook into" a component's [render cycle](/learn/render-and-commit). Add two state variables at the top of `FilterableProductTable` and specify the initial state of your application: +用 [`useState()` Hook](/apis/usestate) 为组件添加 state。Hook 可以 "钩住" 组件的 [渲染周期](/learn/render-and-commit)。在 `FilterableProductTable` 的顶部添加两个 state 变量,用于指定你应用程序的初始 state: ```js function FilterableProductTable({ products }) { @@ -296,7 +296,7 @@ function FilterableProductTable({ products }) {
``` -你可以看见应用程序如何反应。在下面的沙盒代码,过修改`useState('')` 为 `useState('fruit')` 以编辑 `filterText` 的初始值,将会看到搜索输入值和表格更新: +你可以查看你应用程序的表现。在下面的沙盒代码中,通过修改`useState('')` 为 `useState('fruit')` 以编辑 `filterText` 的初始值,你将会发现搜索输入框和表格发生更新: @@ -438,8 +438,7 @@ td { -在上面的沙盒中,`ProductTable` 和 `SearchBar` 读取 `filterText` 和 `inStockOnly` props 以渲染表格、输入、复选框。 -举个例子,里展示了 `SearchBar` 如何填充输入的值: +在上面的沙盒中,`ProductTable` 和 `SearchBar` 读取 `filterText` 和 `inStockOnly` props 以渲染表格、输入、复选框。举个例子,这里展示了 `SearchBar` 如何填充输入的值: ```js {1,6} function SearchBar({ filterText, inStockOnly }) { @@ -462,7 +461,6 @@ React 使数据流显式展示,是与双向数据绑定相比,需要更多 当用户更改表单输入时, state 将更新以反映这些更改。state 由 `FilterableProductTable` 所拥有,以只有它可以调用 `setFilterText` 和 `setInStockOnly`。使 `SearchBar` 更新 `FilterableProductTable` 的 state,需要将这些函数传递到 `SearchBar`: - ```js {2,3,10,11} function FilterableProductTable({ products }) { const [filterText, setFilterText] = useState(''); @@ -639,6 +637,6 @@ td { 你可以在 [添加交互](/learn/adding-interactivity) 这一章节,学习到所有处理事件和更新 state 的内容。 -## 自此该往何处 {/*where-to-go-from-here*/} +## 下一节,我该做什么? {/*where-to-go-from-here*/} -本章只是一个概述,旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation),或者 [深入了解在教程中用到的所有语法](/learn/describing-the-ui)。 +本章只是一个概述,旨在告诉你如何使用 React 如何进行思考构建组件和应用程序。你可以即刻 [开始一个 React 项目](/learn/installation),或者在本教程中 [深入了解所有语法](/learn/describing-the-ui)。 From d3bd4c320b2d7ac3643af8d617de44e7c87a0dfd Mon Sep 17 00:00:00 2001 From: QiChang Li Date: Fri, 27 May 2022 10:57:09 +0800 Subject: [PATCH 09/11] Update beta/src/pages/learn/thinking-in-react.md Co-authored-by: mophia --- beta/src/pages/learn/thinking-in-react.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 68c07fc252..02a21b1f1d 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -266,7 +266,7 @@ Props 和 state 是不同的,但它们可以共同工作。父组件将经常 现在为这个 state 贯彻我们的策略: -1. **验证组件使用 state:** +1. **验证使用 state 的组件:** * `ProductTable` 需要基于 state (搜索文本和复选框值) 过滤产品列表。 * `SearchBar` 需要展示 state (搜索文本和复选框值)。 2. **寻找它们的父组件:** 它们的第一个共同父组件为 `FilterableProductTable`。 From 59cce7f6396d966413d70c2f6f36166723727ea6 Mon Sep 17 00:00:00 2001 From: QiChang Li Date: Fri, 27 May 2022 10:58:46 +0800 Subject: [PATCH 10/11] Update beta/src/pages/learn/thinking-in-react.md Co-authored-by: mophia --- beta/src/pages/learn/thinking-in-react.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 02a21b1f1d..30f90225eb 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -3,6 +3,8 @@ title: React 哲学 translators: - HerbertHe - KnowsCount + - mophia + - QC-L --- From d061987436a828a1de4b25716b649ed44b915b27 Mon Sep 17 00:00:00 2001 From: QiChang Li Date: Fri, 27 May 2022 11:03:48 +0800 Subject: [PATCH 11/11] Update beta/src/pages/learn/thinking-in-react.md --- beta/src/pages/learn/thinking-in-react.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beta/src/pages/learn/thinking-in-react.md b/beta/src/pages/learn/thinking-in-react.md index 30f90225eb..c7e26023ac 100644 --- a/beta/src/pages/learn/thinking-in-react.md +++ b/beta/src/pages/learn/thinking-in-react.md @@ -200,7 +200,7 @@ td {
-(If this code looks intimidating, go through the [Quick Start](/learn/) first!) +(如果你无法理解这段代码,请先阅读 [快速入门](/learn/) 章节!) 在构建你的组件之后,即拥有一个渲染数据模型的可复用组件库。因为这是一个静态应用程序,组件仅返回 JSX。最顶层组件 (`FilterableProductTable`) 将接收你的数据模型作为其 prop。这被称之为 _单向数据流_,因为数据从树的顶层组件传递到下面的组件。