From 29c06690465cc3ef79272958d142d81877733535 Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Tue, 19 Feb 2019 03:56:23 -0800 Subject: [PATCH 1/8] Begin thinking-in-react --- content/docs/thinking-in-react.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 7b2e2e7e6..3fee4ebca 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -1,6 +1,6 @@ --- id: thinking-in-react -title: Thinking in React +title: 用 React 思考 permalink: docs/thinking-in-react.html redirect_from: - 'blog/2013/11/05/thinking-in-react.html' @@ -8,11 +8,11 @@ redirect_from: prev: composition-vs-inheritance.html --- -React is, in our opinion, the premier way to build big, fast Web apps with JavaScript. It has scaled very well for us at Facebook and Instagram. +在我們的意見中,React 是用 JavaScript 建立大型、快速的網路應用程式最首要的方式。它對於在 Facebook 和 Instagram 的我們來說能很有效的增加規模。 -One of the many great parts of React is how it makes you think about apps as you build them. In this document, we'll walk you through the thought process of building a searchable product data table using React. +React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你體會用 React 來建立一個可搜尋的產品數據表格的思考過程。 -## Start With A Mock {#start-with-a-mock} +## 從模擬開始 {#start-with-a-mock} Imagine that we already have a JSON API and a mock from our designer. The mock looks like this: @@ -31,7 +31,7 @@ Our JSON API returns some data that looks like this: ]; ``` -## Step 1: Break The UI Into A Component Hierarchy {#step-1-break-the-ui-into-a-component-hierarchy} +## 第一步:Break The UI Into A Component Hierarchy {#step-1-break-the-ui-into-a-component-hierarchy} The first thing you'll want to do is to draw boxes around every component (and subcomponent) in the mock and give them all names. If you're working with a designer, they may have already done this, so go talk to them! Their Photoshop layer names may end up being the names of your React components! @@ -59,7 +59,7 @@ Now that we've identified the components in our mock, let's arrange them into a * `ProductCategoryRow` * `ProductRow` -## Step 2: Build A Static Version in React {#step-2-build-a-static-version-in-react} +## 第二步:Build A Static Version in React {#step-2-build-a-static-version-in-react}

See the Pen Thinking In React: Step 2 on CodePen.

@@ -78,7 +78,7 @@ Simply refer to the [React docs](/docs/) if you need help executing this step. There are two types of "model" data in React: props and state. It's important to understand the distinction between the two; skim [the official React docs](/docs/interactivity-and-dynamic-uis.html) if you aren't sure what the difference is. -## Step 3: Identify The Minimal (but complete) Representation Of UI State {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} +## 第三步:Identify The Minimal (but complete) Representation Of UI State {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} To make your UI interactive, you need to be able to trigger changes to your underlying data model. React makes this easy with **state**. @@ -104,7 +104,7 @@ So finally, our state is: * The search text the user has entered * The value of the checkbox -## Step 4: Identify Where Your State Should Live {#step-4-identify-where-your-state-should-live} +## 第四步:Identify Where Your State Should Live {#step-4-identify-where-your-state-should-live}

See the Pen Thinking In React: Step 4 on CodePen.

@@ -129,7 +129,7 @@ Cool, so we've decided that our state lives in `FilterableProductTable`. First, You can start seeing how your application will behave: set `filterText` to `"ball"` and refresh your app. You'll see that the data table is updated correctly. -## Step 5: Add Inverse Data Flow {#step-5-add-inverse-data-flow} +## 第五步:Add Inverse Data Flow {#step-5-add-inverse-data-flow}

See the Pen Thinking In React: Step 5 on CodePen.

@@ -143,6 +143,6 @@ Let's think about what we want to happen. We want to make sure that whenever the Though this sounds complex, it's really just a few lines of code. And it's really explicit how your data is flowing throughout the app. -## And That's It {#and-thats-it} +## 完成 {#and-thats-it} Hopefully, this gives you an idea of how to think about building components and applications with React. While it may be a little more typing than you're used to, remember that code is read far more than it's written, and it's extremely easy to read this modular, explicit code. As you start to build large libraries of components, you'll appreciate this explicitness and modularity, and with code reuse, your lines of code will start to shrink. :) From e92c1c3a7fd96e8ec088b8871792ae65e2efc010 Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Tue, 19 Feb 2019 15:50:54 -0800 Subject: [PATCH 2/8] Work in thinking-in-react --- content/docs/thinking-in-react.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 3fee4ebca..fda26cdf7 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -12,13 +12,13 @@ prev: composition-vs-inheritance.html React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你體會用 React 來建立一個可搜尋的產品數據表格的思考過程。 -## 從模擬開始 {#start-with-a-mock} +## 從視覺稿開始 {#start-with-a-mock} -Imagine that we already have a JSON API and a mock from our designer. The mock looks like this: +想像一下我們已經有個 JSON API 和一個設計師給我們的產品視覺稿。這個視覺稿看起來像這樣: ![Mockup](../images/blog/thinking-in-react-mock.png) -Our JSON API returns some data that looks like this: +我們的 JSON API 則會回傳一些看起來像這樣的數據: ``` [ @@ -31,7 +31,7 @@ Our JSON API returns some data that looks like this: ]; ``` -## 第一步:Break The UI Into A Component Hierarchy {#step-1-break-the-ui-into-a-component-hierarchy} +## 第一步:將 Break The UI Into A Component Hierarchy {#step-1-break-the-ui-into-a-component-hierarchy} The first thing you'll want to do is to draw boxes around every component (and subcomponent) in the mock and give them all names. If you're working with a designer, they may have already done this, so go talk to them! Their Photoshop layer names may end up being the names of your React components! From fd2f820c0d751eb6c6ff8b6b91877496ee4ace7d Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Mon, 25 Mar 2019 17:17:13 -0700 Subject: [PATCH 3/8] Fix typo --- content/docs/thinking-in-react.md | 129 +++++++++++++++--------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index fda26cdf7..75021e229 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -10,15 +10,15 @@ prev: composition-vs-inheritance.html 在我們的意見中,React 是用 JavaScript 建立大型、快速的網路應用程式最首要的方式。它對於在 Facebook 和 Instagram 的我們來說能很有效的增加規模。 -React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你體會用 React 來建立一個可搜尋的產品數據表格的思考過程。 +React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你體會用 React 來建立一個可搜尋的產品資料表格的思考過程。 ## 從視覺稿開始 {#start-with-a-mock} 想像一下我們已經有個 JSON API 和一個設計師給我們的產品視覺稿。這個視覺稿看起來像這樣: -![Mockup](../images/blog/thinking-in-react-mock.png) +![視覺稿](../images/blog/thinking-in-react-mock.png) -我們的 JSON API 則會回傳一些看起來像這樣的數據: +我們的 JSON API 則會回傳一些看起來像這樣的資料: ``` [ @@ -31,27 +31,27 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 ]; ``` -## 第一步:將 Break The UI Into A Component Hierarchy {#step-1-break-the-ui-into-a-component-hierarchy} +## 第一步:將 UI 拆解成 component 層級 {#step-1-break-the-ui-into-a-component-hierarchy} -The first thing you'll want to do is to draw boxes around every component (and subcomponent) in the mock and give them all names. If you're working with a designer, they may have already done this, so go talk to them! Their Photoshop layer names may end up being the names of your React components! +首先,你要做的是將視覺稿中每一個 component (及 subcomponent)都圈起來,並幫它們命名。如果你在跟設計師合作的話,他們可能已經幫你做好這一步了,所以跟他們聊聊吧!他們在 Photoshop 中所用的圖層的名字可能可以作為你的 React component 的名字! -But how do you know what should be its own component? Just 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. +但是你要怎麼知道哪一個東西應該是自己獨立一個 component 呢?就用和你決定建立一個新的 function 或 object 一樣的準則即可。其中一個技巧是[單一責任原則](https://en.wikipedia.org/wiki/Single_responsibility_principle),它的意思是:在我們的理想中,一個 component應該只負責做一件事情。如果這個 component 最後變大了,你就需要再將它分成數個更小的 subcomponent 。 -Since you're often displaying a JSON data model to a user, you'll find that if your model was built correctly, your UI (and therefore your component structure) will map nicely. That's because UI and data models tend to adhere to the same *information architecture*, which means the work of separating your UI into components is often trivial. Just break it up into components that represent exactly one piece of your data model. +由於你常常會展示 JSON 的資料模型給使用者,你會發現,如果你的模式是正確地被建立的話,你的 UI(以及你的 component 結構)就會很好的對應起來。這是因為 UI 和資料模型通常是遵守相同的*資訊架構*,這意味著將你的 UI 拆成 component 通常是相當容易的。只要將 UI 分解成數個 component,每一個都明確代表著你的資料模型中的某一部份即可。 -![Component diagram](../images/blog/thinking-in-react-components.png) +![Component 架構圖](../images/blog/thinking-in-react-components.png) -You'll see here that we have five components in our simple app. We've italicized the data each component represents. +你會看到在這裡我們簡單的應用程式中有五個 component。我們把每個 component 所代表的資料都斜體化了。 - 1. **`FilterableProductTable` (orange):** contains the entirety of the example - 2. **`SearchBar` (blue):** receives all *user input* - 3. **`ProductTable` (green):** displays and filters the *data collection* based on *user input* - 4. **`ProductCategoryRow` (turquoise):** displays a heading for each *category* - 5. **`ProductRow` (red):** displays a row for each *product* + 1. **`FilterableProductTable`(橘色):** 包含整個範例 + 2. **`SearchBar`(藍色):** 接收所有 *使用者的輸入* + 3. **`ProductTable`(綠色):** 展示並過濾根據*使用者輸入*的*資料集* + 4. **`ProductCategoryRow`(土耳其藍色):** 為每個*列別*展示標題 + 5. **`ProductRow`(紅色):** 為每個*產品*展示一列 -If you look at `ProductTable`, 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 there's an argument to be made either way. For this example, we left it as part of `ProductTable` because it is part of rendering the *data collection* which is `ProductTable`'s responsibility. However, if this header grows to be complex (i.e. if we were to add affordances for sorting), it would certainly make sense to make this its own `ProductTableHeader` component. +如果你看看 `ProductTable`,你會發現表格的標題列(內含「Name」和「Price」標籤 )並非獨立的 component。要不要把它們變成 component 這個議題完全是個人的喜好,正反意見都有。在這邊的例子裡面,我們把它當作 `ProductTable` 的一部分,因為它是 rendering *資料集* 的一部分,而這正是 `ProductTable` 這個 component 的責任。然而,如果標題欄之後變得越來越複雜(也就是如果我們要加上可以分類的直觀功能的話),那麼建立一個獨立的 `ProductTableHeader` component 就非常合理。 -Now that we've identified the components in our mock, let's arrange them into a hierarchy. This is easy. Components that appear within another component in the mock should appear as a child in the hierarchy: +既然我們已經找出視覺稿中的 component 了,讓我們來安排它們的層級。這很容易。在視覺稿中,在另一個 component 中出現的 component 就應該是 child 的層級: * `FilterableProductTable` * `SearchBar` @@ -59,90 +59,91 @@ Now that we've identified the components in our mock, let's arrange them into a * `ProductCategoryRow` * `ProductRow` -## 第二步:Build A Static Version in React {#step-2-build-a-static-version-in-react} +## 第二步:在 React 中建立一個靜態版本 {#step-2-build-a-static-version-in-react} -

See the Pen Thinking In React: Step 2 on CodePen.

+

CodePen 中看用 React 思考:第二步

-Now that you have your component hierarchy, it's time to implement your app. The easiest way is to build a version that takes your data model and renders the UI but has no interactivity. It's best to decouple these processes because building a static version requires a lot of typing and no thinking, and adding interactivity requires a lot of thinking and not a lot of typing. We'll see why. +在你有了 component 層級後,就可以開始實作你的應用程式了。最簡單的方式是為你的應用程式建立一個接收資料模型、render UI 且沒有互動性的版本。建立一個靜態版本需要打很多字,但不需要想很多,而加上互動性則相反,需要做很多的思考,很少的打字,所以最好的方式是把這幾個過程都分開來。接下來,我們會知道為什麼是如此。 -To build a static version of your app that renders your data model, you'll want to build components that reuse other components and pass data using *props*. *props* are a way of passing data from parent to child. If you're familiar with the concept of *state*, **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. +為你的應用程式建立一個 render 資料模型的版本,你會想要建立可以重複使用其他 component 的 component,並使用 *props* 傳遞資料。*Props* 是將資料從 parent 傳給 child 的方式。如果你對於 *state* 的概念很熟悉的話,請**完全不要使用 state** 來建立這個靜態版本。State 是保留給互動性的,也就是會隨時間改變的資料。既然我們目前要做的是這應用程式的靜態版本,你就不需要 state。 -You can build top-down or bottom-up. That is, you can either start with building the components higher up in the hierarchy (i.e. starting with `FilterableProductTable`) or with the ones lower in it (`ProductRow`). In simpler examples, it's usually easier to go top-down, and on larger projects, it's easier to go bottom-up and write tests as you build. +你可以從最上層開始,或從最下層開始。也就是說,你可以先從層級較高的 component 開始做起(也就是從 `FilterableProductTable` 開始),或者你也可以從比它低層級的(`ProductRow`)開始。在比較簡單的例子中,通常從上往下是比較簡單的。在較為大型的專案中,從下往上、邊寫邊測試則比較容易。 -At the end of this step, you'll have a library of reusable components that render your data model. The components will only have `render()` methods since this is a static version of your app. The component at the top of the hierarchy (`FilterableProductTable`) will take your data model as a prop. If you make a change to your underlying data model and call `ReactDOM.render()` again, the UI will be updated. It's easy to see how your UI is updated and where to make changes since there's nothing complicated going on. React's **one-way data flow** (also called *one-way binding*) keeps everything modular and fast. +在這一步的最後,你會有一個函式庫的可重複使用的 component 來 render 你的資料模型。這些 component 只會有 `render()` 方法,因為這是你應用程式的靜態版本。最高層級的 component (`FilterableProductTable`) 會接收你的資料模型作為 prop。如果你改變底層的資料模型並再次呼叫 `ReactDOM.render()` 的話,那麼 UI 就會被更新。看到你的 UI 被更新以及哪裡該被改變是很容易的,因為目前為止還沒有任何複雜的事發生。React 的 **單向資料流**(也可稱為*單向綁定*)確保所有 component 都是模塊化且快速的。 -Simply refer to the [React docs](/docs/) if you need help executing this step. +如果你需要幫助來執行這一步的話,請參考這份 [React 文件](/docs/)。 -### A Brief Interlude: Props vs State {#a-brief-interlude-props-vs-state} +### 簡短的插曲:Props 和 State {#a-brief-interlude-props-vs-state} -There are two types of "model" data in React: props and state. It's important to understand the distinction between the two; skim [the official React docs](/docs/interactivity-and-dynamic-uis.html) if you aren't sure what the difference is. +React 中有兩種「模型」資料: props and state。理解兩者的差別至關重要。若你不確定兩者的差別,請瀏覽 [React 的官方文件](/docs/interactivity-and-dynamic-uis.html)。 -## 第三步:Identify The Minimal (but complete) Representation Of UI State {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} +## 第三步:指名最小(但完整)的 UI State 的代表 Identify The Minimal (but complete) Representation Of UI State {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} -To make your UI interactive, you need to be able to trigger changes to your underlying data model. React makes this easy with **state**. +為了將你的 UI 變成有互動性,你需要有辦法觸發底層的資料模型做出改變。React 使用 **state** 把這件事變容易了。 -To build your app correctly, you first need to think of the minimal set of mutable state that your app needs. The key here is [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 you need on-demand. For example, if you're building a TODO list, just keep an array of the TODO items around; don't keep a separate state variable for the count. Instead, when you want to render the TODO count, simply take the length of the TODO items array. +為了正確地建立你的應用程式,你首先需要思考你的應用程式最少需要哪些可變的 state。這裡的關鍵是 [DRY:*避免重複代碼原則*](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。請找出你的應用程式所需的最少的 representation 並在你遇到其他問題時再 compute everything else you need on-demand。例如,如果你在建立一個待辦清單,就先使用一個代表待辦事項的 array。不要另外用一個獨立的 state 變數來追蹤數量。當你要 render 代辦事項的數量時,讀取待辦事項 array 的長度即可。 -Think of all of the pieces of data in our example application. We have: +思考我們範例中應用程式的所有資料。我們現在有: - * The original list of products - * The search text the user has entered - * The value of the checkbox - * The filtered list of products + * 原本的產品列表 + * 使用者輸入的搜尋關鍵字 + * 複選框的值 + * 篩選過後的產品列表 -Let's go through each one and figure out which one is state. Simply ask three questions about each piece of data: +讓我們來看一下每一個資料,並找出哪一個是 state。對於每一個資料,問你自己這三個問題: - 1. Is it passed in from a parent via props? If so, it probably isn't state. - 2. Does it remain unchanged over time? If so, it probably isn't state. - 3. Can you compute it based on any other state or props in your component? If so, it isn't state. + 1. 這個資料是從 parent 透過 props 傳下來的嗎?如果是的話,那它很可能不是 state。 + 2. 這個資料是否一直保持不變呢?如果是的話,那它很可能不是 state。 + 3. 你是否可以根據你的 component 中其他的 state 或 prop 來計算這個資料呢?如果是的話,那它一定不是 state。 -The original list of products is passed in as props, so that's not state. The search text and the checkbox seem to be state since they change over time and can't be computed from anything. And finally, the filtered list of products isn't state because it can be computed by combining the original list of products with the search text and value of the checkbox. +原本的產品列表是被當作 prop 往下傳的,所以它不是 state。搜尋關鍵字和複選框看起來可能是 state,因為它們會隨時間而改變,也不能從其他東西中被計算出來。最後,篩選過後的產品列表不是 state,因為它能透過結合原本的產品列表、搜尋關鍵字和複選框的值被計算出來。 -So finally, our state is: +所以,我們的 state 是: - * The search text the user has entered - * The value of the checkbox + * 使用者輸入的搜尋關鍵字 + * 複選框的值 -## 第四步:Identify Where Your State Should Live {#step-4-identify-where-your-state-should-live} +## 第四步:找出你的 State 應該在哪裡 {#step-4-identify-where-your-state-should-live} -

See the Pen Thinking In React: Step 4 on CodePen.

+

CodePen 中看用 React 思考:第四步

-OK, so we've identified what the minimal set of app state is. Next, we need to identify which component mutates, or *owns*, this state. +OK,所以我們已經找出這個應用程式最少的 state 是哪些了。下一步,我們需要找出哪幾個 component 會 mutate,或者*擁有*,這個 state。 -Remember: React is all about one-way data flow down the component hierarchy. It may not be immediately clear which component should own what state. **This is often the most challenging part for newcomers to understand,** so follow these steps to figure it out: +請記得,React 的核心精神是單向資料流,從 component 的層級從高往下流。也許哪個 component 該擁有 state 在一開始並不是很明顯。**對新手來說,這往往是最難理解的概念**,所以請跟著以下的步驟來思考: -For each piece of state in your application: +在你的應用程式中的每個 state: - * Identify every component that renders something based on that state. - * Find a common owner component (a single component above all the components that need the state in the hierarchy). - * Either the common owner or another component higher up in the hierarchy should own the state. - * If you can't find a component where it makes sense to own the state, create a new component simply for holding the state and add it somewhere in the hierarchy above the common owner component. + * 指出每個根據 state 來 render 某些東西的 component。 + * 找出一個共同擁有者 component(在層級中單一一個需要 state 的、在所有的 component 之上的 component)。 + * 應該擁有 state 的會是共同擁有者 component 或另一個更高層級的 component。 + * 如果你找不出一個應該擁有 state 的 component 的話,那就建立一個新的 component 來保持 state,並把它加到層級中共同擁有者 component 之上的某處。 -Let's run through this strategy for our application: +讓我們來討論一下我們應用程式的這個策略: - * `ProductTable` needs to filter the product list based on state and `SearchBar` needs to display the search text and checked state. - * The common owner component is `FilterableProductTable`. - * It conceptually makes sense for the filter text and checked value to live in `FilterableProductTable` + * `ProductTable` 需要根據 state 來篩選產品列表,而 `SearchBar` 需要展示搜尋關鍵字和複選框的 state。 + * 這兩個 component 的共同擁有者 component 是 `FilterableProductTable`。 + * 概念上來說,篩選過的文字和復選框的值存在於 `FilterableProductTable` 中是合理的。 -Cool, so we've decided that our state lives in `FilterableProductTable`. First, add an instance property `this.state = {filterText: '', inStockOnly: false}` to `FilterableProductTable`'s `constructor` to reflect the initial state of your application. Then, pass `filterText` and `inStockOnly` to `ProductTable` and `SearchBar` as a prop. Finally, use these props to filter the rows in `ProductTable` and set the values of the form fields in `SearchBar`. +很好,所以我們現在已經決定我們的 state 會存在於 `FilterableProductTable` 之中。首先,把這個實例的 property `this.state = {filterText: '', inStockOnly: false}` 加到 `FilterableProductTable` 的 `constructor` 裡面以反映你的應用程式的初始 state。接著,把 `filterText` 和 `inStockOnly` 作為 prop 傳給 `ProductTable` 和 `SearchBar`。最後,用這些 prop 來篩選 `ProductTable` 中的列,並設定 `SearchBar` 中的表格欄的值。 -You can start seeing how your application will behave: set `filterText` to `"ball"` and refresh your app. You'll see that the data table is updated correctly. +你可以開始看到你的應用程式會如何運作:將 `filterText` 設定為 `「ball」` 並更新你的程式。你會看到資料表被正確地更新了。 -## 第五步:Add Inverse Data Flow {#step-5-add-inverse-data-flow} +## 第五步:加入相反的資料流 {#step-5-add-inverse-data-flow} -

See the Pen Thinking In React: Step 5 on CodePen.

+

CodePen 中看用 React 思考:第四步

-So far, we've built an app that renders correctly as a function of props and state flowing down the hierarchy. Now it's time to support data flowing the other way: the form components deep in the hierarchy need to update the state in `FilterableProductTable`. +到目前為止,我們已經建立了一個作為含有從層級由上往下傳 props 和 state 的、且可以正確 render 的 function 的應用程式。現在是時候支援另一種資料流的方向了:在層級深處的表格 component 需要更新 `FilterableProductTable` 的 state。 -React makes this data flow explicit to make it easy to understand how your program works, but it does require a little more typing than traditional two-way data binding. +React 將這種資料流明確表示出來,以便讓你能更容易理解你的程式如何運作,但是這的確比傳統的雙向資料綁定需要打多一點字。 -If you try to type or check the box in the current version of the example, you'll see that React ignores your input. This is intentional, as we've set the `value` prop of the `input` to always be equal to the `state` passed in from `FilterableProductTable`. +如果你試著在範例目前的版本中印出或勾選複選框,你會看到 React 無視你的輸入。這是刻意的,因為我們把 `input` 的 `value` prop 設定為永遠和從 `FilterableProductTable` 傳下來的 `state` ㄧ樣。 -Let's think about what we want to happen. We want to make sure that whenever the user changes the form, we update the state to reflect the user input. Since components should only update their own state, `FilterableProductTable` will pass callbacks to `SearchBar` that will fire whenever the state should be updated. We can use the `onChange` event on the inputs to be notified of it. The callbacks passed by `FilterableProductTable` will call `setState()`, and the app will be updated. +讓我們思考一下我們想要做些什麼。我們想確保當使用者改變這個表格時,我們會更新 state 以反映使用者的輸入。既然 component 只應該更新它自己本身的 state, `FilterableProductTable` 將會把 callback 傳給 `SearchBar`,而它們則會在 state 該被更新的時候被觸發。我們可以在輸入上使用 `onChange` 這個 event 來 +到通師。 被 `FilterableProductTable` 傳下來的 callback 則會呼叫 `setState()`,之後應用程式就會被更新。 -Though this sounds complex, it's really just a few lines of code. And it's really explicit how your data is flowing throughout the app. +雖然這聽起來負責,但實際上這所用的程式碼很少。而你的資料在應用程式中流動的方向是非常明確的。 ## 完成 {#and-thats-it} -Hopefully, this gives you an idea of how to think about building components and applications with React. While it may be a little more typing than you're used to, remember that code is read far more than it's written, and it's extremely easy to read this modular, explicit code. As you start to build large libraries of components, you'll appreciate this explicitness and modularity, and with code reuse, your lines of code will start to shrink. :) +希望這幫助你理解如何用 React 建立 component 和應用程式。雖然這可能需要你比你習慣的多打一些程式碼,請記得閱讀程式碼比起寫程式碼更常發生,而閱讀這種模組化、清晰明確的程式碼是非常容易的。當你開始建立大型的 component 函式庫時,你會很感激這樣的明確性和模組性,而當你開始重複使用程式碼時,你的程式的行數會開始減少。:) From 4a0705a647be6013b95090d04d44602d81afbde5 Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Mon, 25 Mar 2019 17:19:57 -0700 Subject: [PATCH 4/8] Fix typo --- content/docs/thinking-in-react.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 75021e229..efba7ed20 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -51,7 +51,7 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 如果你看看 `ProductTable`,你會發現表格的標題列(內含「Name」和「Price」標籤 )並非獨立的 component。要不要把它們變成 component 這個議題完全是個人的喜好,正反意見都有。在這邊的例子裡面,我們把它當作 `ProductTable` 的一部分,因為它是 rendering *資料集* 的一部分,而這正是 `ProductTable` 這個 component 的責任。然而,如果標題欄之後變得越來越複雜(也就是如果我們要加上可以分類的直觀功能的話),那麼建立一個獨立的 `ProductTableHeader` component 就非常合理。 -既然我們已經找出視覺稿中的 component 了,讓我們來安排它們的層級。這很容易。在視覺稿中,在另一個 component 中出現的 component 就應該是 child 的層級: +既然我們已經找出視覺稿中的 component 了,讓我們來安排它們的層級。這很容易。在視覺稿中,在另一個 component 中出現的 component 就應該是 childgi: * `FilterableProductTable` * `SearchBar` From c5828ee2d5856e3794385549ea5721c4dd52727e Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Mon, 25 Mar 2019 17:22:05 -0700 Subject: [PATCH 5/8] Fix typo --- content/docs/thinking-in-react.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index efba7ed20..2c9c5c245 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -49,9 +49,9 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 4. **`ProductCategoryRow`(土耳其藍色):** 為每個*列別*展示標題 5. **`ProductRow`(紅色):** 為每個*產品*展示一列 -如果你看看 `ProductTable`,你會發現表格的標題列(內含「Name」和「Price」標籤 )並非獨立的 component。要不要把它們變成 component 這個議題完全是個人的喜好,正反意見都有。在這邊的例子裡面,我們把它當作 `ProductTable` 的一部分,因為它是 rendering *資料集* 的一部分,而這正是 `ProductTable` 這個 component 的責任。然而,如果標題欄之後變得越來越複雜(也就是如果我們要加上可以分類的直觀功能的話),那麼建立一個獨立的 `ProductTableHeader` component 就非常合理。 +如果你看看 `ProductTable`,你會發現表格的標題列(內含「Name」和「Price」標籤 )並非獨立的 component。要不要把它們變成 component 這個議題完全是個人的喜好,正反意見都有。在這邊的例子裡面,我們把它當作 `ProductTable` 的一部分,因為它是 rendering *數據集* 的一部分,而這正是 `ProductTable` 這個 component 的責任。然而,如果標題欄之後變得越來越複雜(也就是如果我們要加上可以分類的 affordance 的話),那麼建立一個獨立的 `ProductTableHeader` component 就非常合理。 -既然我們已經找出視覺稿中的 component 了,讓我們來安排它們的層級。這很容易。在視覺稿中,在另一個 component 中出現的 component 就應該是 childgi: +既然我們已經找出視覺稿中的 component 了,讓我們來安排它們的層級。這很容易。在視覺稿中,在另一個 component 中出現的 component 就應該是 child: * `FilterableProductTable` * `SearchBar` @@ -68,7 +68,7 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 為你的應用程式建立一個 render 資料模型的版本,你會想要建立可以重複使用其他 component 的 component,並使用 *props* 傳遞資料。*Props* 是將資料從 parent 傳給 child 的方式。如果你對於 *state* 的概念很熟悉的話,請**完全不要使用 state** 來建立這個靜態版本。State 是保留給互動性的,也就是會隨時間改變的資料。既然我們目前要做的是這應用程式的靜態版本,你就不需要 state。 -你可以從最上層開始,或從最下層開始。也就是說,你可以先從層級較高的 component 開始做起(也就是從 `FilterableProductTable` 開始),或者你也可以從比它低層級的(`ProductRow`)開始。在比較簡單的例子中,通常從上往下是比較簡單的。在較為大型的專案中,從下往上、邊寫邊測試則比較容易。 +你可以從最上層開始,或從最下層開始。也就是說,你可以先從層級較高的 component 開始做起(也就是從 `FilterableProductTable` 開始),或者你也可以從比它低層級的(`ProductRow`)開始。在比較簡單的例子中,通常從上往下是比較簡單的。但在較為大型的專案中,從下往上、邊寫邊測試則比較容易。 在這一步的最後,你會有一個函式庫的可重複使用的 component 來 render 你的資料模型。這些 component 只會有 `render()` 方法,因為這是你應用程式的靜態版本。最高層級的 component (`FilterableProductTable`) 會接收你的資料模型作為 prop。如果你改變底層的資料模型並再次呼叫 `ReactDOM.render()` 的話,那麼 UI 就會被更新。看到你的 UI 被更新以及哪裡該被改變是很容易的,因為目前為止還沒有任何複雜的事發生。React 的 **單向資料流**(也可稱為*單向綁定*)確保所有 component 都是模塊化且快速的。 @@ -78,11 +78,11 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 React 中有兩種「模型」資料: props and state。理解兩者的差別至關重要。若你不確定兩者的差別,請瀏覽 [React 的官方文件](/docs/interactivity-and-dynamic-uis.html)。 -## 第三步:指名最小(但完整)的 UI State 的代表 Identify The Minimal (but complete) Representation Of UI State {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} +## 第三步:找出最少(但完整)的 UI State 的代表 {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} 為了將你的 UI 變成有互動性,你需要有辦法觸發底層的資料模型做出改變。React 使用 **state** 把這件事變容易了。 -為了正確地建立你的應用程式,你首先需要思考你的應用程式最少需要哪些可變的 state。這裡的關鍵是 [DRY:*避免重複代碼原則*](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。請找出你的應用程式所需的最少的 representation 並在你遇到其他問題時再 compute everything else you need on-demand。例如,如果你在建立一個待辦清單,就先使用一個代表待辦事項的 array。不要另外用一個獨立的 state 變數來追蹤數量。當你要 render 代辦事項的數量時,讀取待辦事項 array 的長度即可。 +為了正確地建立你的應用程式,你首先需要思考你的應用程式最少需要哪些可變的 state。這裡的關鍵是 [DRY:*避免重複代碼原則*](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。請找出你的應用程式所需的最少的 representation,並在你遇到其他東西時再計算它們。例如,如果你在建立一個待辦清單,就先使用一個可以用來代表待辦事項的 array。不要另外用一個獨立的 state 變數來追蹤數量。當你要 render 代辦事項的數量時,讀取待辦事項 array 的長度即可。 思考我們範例中應用程式的所有資料。我們現在有: @@ -140,10 +140,10 @@ React 將這種資料流明確表示出來,以便讓你能更容易理解你 如果你試著在範例目前的版本中印出或勾選複選框,你會看到 React 無視你的輸入。這是刻意的,因為我們把 `input` 的 `value` prop 設定為永遠和從 `FilterableProductTable` 傳下來的 `state` ㄧ樣。 讓我們思考一下我們想要做些什麼。我們想確保當使用者改變這個表格時,我們會更新 state 以反映使用者的輸入。既然 component 只應該更新它自己本身的 state, `FilterableProductTable` 將會把 callback 傳給 `SearchBar`,而它們則會在 state 該被更新的時候被觸發。我們可以在輸入上使用 `onChange` 這個 event 來 -到通師。 被 `FilterableProductTable` 傳下來的 callback 則會呼叫 `setState()`,之後應用程式就會被更新。 +接收通知。被 `FilterableProductTable` 傳下來的 callback 則會呼叫 `setState()`,之後應用程式就會被更新。 雖然這聽起來負責,但實際上這所用的程式碼很少。而你的資料在應用程式中流動的方向是非常明確的。 ## 完成 {#and-thats-it} -希望這幫助你理解如何用 React 建立 component 和應用程式。雖然這可能需要你比你習慣的多打一些程式碼,請記得閱讀程式碼比起寫程式碼更常發生,而閱讀這種模組化、清晰明確的程式碼是非常容易的。當你開始建立大型的 component 函式庫時,你會很感激這樣的明確性和模組性,而當你開始重複使用程式碼時,你的程式的行數會開始減少。:) +希望這幫助你理解如何用 React 建立 component 和應用程式。雖然這可能需要你比你習慣的多打一些程式碼,請記得閱讀程式碼比起寫程式碼更常發生,而閱讀這種模組化、清晰明確的程式碼是非常容易的。當你開始建立大型的 component 函式庫時,你會很感激有這樣的明確性和模組性,而當你開始重複使用程式碼時,你的程式的行數會開始減少。:) From 4d1964533e8d91799ba189482a24d09d0d4775ee Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Mon, 25 Mar 2019 00:12:09 -0700 Subject: [PATCH 6/8] Fix typos --- content/docs/thinking-in-react.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 2c9c5c245..e589678d5 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -10,7 +10,11 @@ prev: composition-vs-inheritance.html 在我們的意見中,React 是用 JavaScript 建立大型、快速的網路應用程式最首要的方式。它對於在 Facebook 和 Instagram 的我們來說能很有效的增加規模。 +<<<<<<< HEAD React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你體會用 React 來建立一個可搜尋的產品資料表格的思考過程。 +======= +React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你走過一遍用 React 來建立一個可搜尋的產品資料表格的思考過程。 +>>>>>>> Fix typos ## 從視覺稿開始 {#start-with-a-mock} @@ -37,7 +41,11 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 但是你要怎麼知道哪一個東西應該是自己獨立一個 component 呢?就用和你決定建立一個新的 function 或 object 一樣的準則即可。其中一個技巧是[單一責任原則](https://en.wikipedia.org/wiki/Single_responsibility_principle),它的意思是:在我們的理想中,一個 component應該只負責做一件事情。如果這個 component 最後變大了,你就需要再將它分成數個更小的 subcomponent 。 +<<<<<<< HEAD 由於你常常會展示 JSON 的資料模型給使用者,你會發現,如果你的模式是正確地被建立的話,你的 UI(以及你的 component 結構)就會很好的對應起來。這是因為 UI 和資料模型通常是遵守相同的*資訊架構*,這意味著將你的 UI 拆成 component 通常是相當容易的。只要將 UI 分解成數個 component,每一個都明確代表著你的資料模型中的某一部份即可。 +======= +由於你常常會展示 JSON 的資料模型給使用者,你會發現,如果你的模式是正確地被建立的話,你的 UI(以及你的 component 結構)會很好的相互對應。這是因為 UI 和資料模型通常是遵守同樣的*資訊架構*,這意味著將你的 UI 拆成 component 通常是相當容易的。只要將 UI 分解成數個 component,每一個都明確代表著你的資料模型中的某一部份即可。 +>>>>>>> Fix typos ![Component 架構圖](../images/blog/thinking-in-react-components.png) @@ -49,7 +57,7 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 4. **`ProductCategoryRow`(土耳其藍色):** 為每個*列別*展示標題 5. **`ProductRow`(紅色):** 為每個*產品*展示一列 -如果你看看 `ProductTable`,你會發現表格的標題列(內含「Name」和「Price」標籤 )並非獨立的 component。要不要把它們變成 component 這個議題完全是個人的喜好,正反意見都有。在這邊的例子裡面,我們把它當作 `ProductTable` 的一部分,因為它是 rendering *數據集* 的一部分,而這正是 `ProductTable` 這個 component 的責任。然而,如果標題欄之後變得越來越複雜(也就是如果我們要加上可以分類的 affordance 的話),那麼建立一個獨立的 `ProductTableHeader` component 就非常合理。 +如果你看看 `ProductTable`,你會發現表格的標題列(內含「Name」和「Price」標籤 )並非獨立的 component。要不要把它們變成 component 這個議題完全是個人的喜好,正反意見都有。在這邊的例子裡面,我們把它當作 `ProductTable` 的一部分,因為它是 rendering *資料集* 的一部分,而這正是 `ProductTable` 這個 component 的責任。然而,如果標題欄之後變得越來越複雜(也就是如果我們要加上可以分類的直觀功能的話),那麼建立一個獨立的 `ProductTableHeader` component 就非常合理。 既然我們已經找出視覺稿中的 component 了,讓我們來安排它們的層級。這很容易。在視覺稿中,在另一個 component 中出現的 component 就應該是 child: @@ -82,13 +90,13 @@ React 中有兩種「模型」資料: props and state。理解兩者的差別 為了將你的 UI 變成有互動性,你需要有辦法觸發底層的資料模型做出改變。React 使用 **state** 把這件事變容易了。 -為了正確地建立你的應用程式,你首先需要思考你的應用程式最少需要哪些可變的 state。這裡的關鍵是 [DRY:*避免重複代碼原則*](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。請找出你的應用程式所需的最少的 representation,並在你遇到其他東西時再計算它們。例如,如果你在建立一個待辦清單,就先使用一個可以用來代表待辦事項的 array。不要另外用一個獨立的 state 變數來追蹤數量。當你要 render 代辦事項的數量時,讀取待辦事項 array 的長度即可。 +為了正確地建立你的應用程式,你首先需要思考你的應用程式最少需要哪些可變的 state。這裡的關鍵是 [DRY:*避免重複代碼原則*](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。請找出你的應用程式所需的最少的呈現方式,並在你遇到其他東西時再計算它們。例如,如果你在建立一個待辦清單,就先使用一個可以用來代表待辦事項的 array。不要另外用一個獨立的 state 變數來追蹤數量。當你要 render 代辦事項的數量時,讀取待辦事項 array 的長度即可。 思考我們範例中應用程式的所有資料。我們現在有: * 原本的產品列表 * 使用者輸入的搜尋關鍵字 - * 複選框的值 + * checkbox 的值 * 篩選過後的產品列表 讓我們來看一下每一個資料,並找出哪一個是 state。對於每一個資料,問你自己這三個問題: @@ -97,12 +105,12 @@ React 中有兩種「模型」資料: props and state。理解兩者的差別 2. 這個資料是否一直保持不變呢?如果是的話,那它很可能不是 state。 3. 你是否可以根據你的 component 中其他的 state 或 prop 來計算這個資料呢?如果是的話,那它一定不是 state。 -原本的產品列表是被當作 prop 往下傳的,所以它不是 state。搜尋關鍵字和複選框看起來可能是 state,因為它們會隨時間而改變,也不能從其他東西中被計算出來。最後,篩選過後的產品列表不是 state,因為它能透過結合原本的產品列表、搜尋關鍵字和複選框的值被計算出來。 +原本的產品列表是被當作 prop 往下傳的,所以它不是 state。搜尋關鍵字和 checkbox 看起來可能是 state,因為它們會隨時間而改變,也不能從其他東西中被計算出來。最後,篩選過後的產品列表不是 state,因為它能透過結合原本的產品列表、搜尋關鍵字和checkbox 的值被計算出來。 所以,我們的 state 是: * 使用者輸入的搜尋關鍵字 - * 複選框的值 + * checkbox 的值 ## 第四步:找出你的 State 應該在哪裡 {#step-4-identify-where-your-state-should-live} @@ -121,7 +129,7 @@ OK,所以我們已經找出這個應用程式最少的 state 是哪些了。 讓我們來討論一下我們應用程式的這個策略: - * `ProductTable` 需要根據 state 來篩選產品列表,而 `SearchBar` 需要展示搜尋關鍵字和複選框的 state。 + * `ProductTable` 需要根據 state 來篩選產品列表,而 `SearchBar` 需要展示搜尋關鍵字和 checkbox 的 state。 * 這兩個 component 的共同擁有者 component 是 `FilterableProductTable`。 * 概念上來說,篩選過的文字和復選框的值存在於 `FilterableProductTable` 中是合理的。 @@ -137,12 +145,12 @@ OK,所以我們已經找出這個應用程式最少的 state 是哪些了。 React 將這種資料流明確表示出來,以便讓你能更容易理解你的程式如何運作,但是這的確比傳統的雙向資料綁定需要打多一點字。 -如果你試著在範例目前的版本中印出或勾選複選框,你會看到 React 無視你的輸入。這是刻意的,因為我們把 `input` 的 `value` prop 設定為永遠和從 `FilterableProductTable` 傳下來的 `state` ㄧ樣。 +如果你試著在範例目前的版本中印出或勾選 checkbox,你會看到 React 無視你的輸入。這是刻意的,因為我們把 `input` 的 `value` prop 設定為永遠和從 `FilterableProductTable` 傳下來的 `state` ㄧ樣。 讓我們思考一下我們想要做些什麼。我們想確保當使用者改變這個表格時,我們會更新 state 以反映使用者的輸入。既然 component 只應該更新它自己本身的 state, `FilterableProductTable` 將會把 callback 傳給 `SearchBar`,而它們則會在 state 該被更新的時候被觸發。我們可以在輸入上使用 `onChange` 這個 event 來 接收通知。被 `FilterableProductTable` 傳下來的 callback 則會呼叫 `setState()`,之後應用程式就會被更新。 -雖然這聽起來負責,但實際上這所用的程式碼很少。而你的資料在應用程式中流動的方向是非常明確的。 +雖然這聽起來很複雜,但實際上這所用的程式碼很少。而你的資料在應用程式中流動的方向是非常明確的。 ## 完成 {#and-thats-it} From 83a6dcaf3636bc82f2008cd6f71ed33587f88289 Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Mon, 25 Mar 2019 17:41:49 -0700 Subject: [PATCH 7/8] Fix typo (step 5) --- content/docs/thinking-in-react.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index e589678d5..1ac855275 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -139,7 +139,7 @@ OK,所以我們已經找出這個應用程式最少的 state 是哪些了。 ## 第五步:加入相反的資料流 {#step-5-add-inverse-data-flow} -

CodePen 中看用 React 思考:第四步

+

CodePen 中看用 React 思考:第五步

到目前為止,我們已經建立了一個作為含有從層級由上往下傳 props 和 state 的、且可以正確 render 的 function 的應用程式。現在是時候支援另一種資料流的方向了:在層級深處的表格 component 需要更新 `FilterableProductTable` 的 state。 From 6db2103621165cf84aad173a80f691f804105aaa Mon Sep 17 00:00:00 2001 From: Chloe Lin Date: Sat, 30 Mar 2019 23:55:00 -0700 Subject: [PATCH 8/8] Resolve conflicts --- content/docs/thinking-in-react.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 1ac855275..25ce62078 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -10,11 +10,7 @@ prev: composition-vs-inheritance.html 在我們的意見中,React 是用 JavaScript 建立大型、快速的網路應用程式最首要的方式。它對於在 Facebook 和 Instagram 的我們來說能很有效的增加規模。 -<<<<<<< HEAD -React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你體會用 React 來建立一個可搜尋的產品資料表格的思考過程。 -======= React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的應用程式。在這個章節中,我們會帶領你走過一遍用 React 來建立一個可搜尋的產品資料表格的思考過程。 ->>>>>>> Fix typos ## 從視覺稿開始 {#start-with-a-mock} @@ -41,11 +37,7 @@ React 眾多的優點之ㄧ是它讓你能在寫程式的同時去思考你的 但是你要怎麼知道哪一個東西應該是自己獨立一個 component 呢?就用和你決定建立一個新的 function 或 object 一樣的準則即可。其中一個技巧是[單一責任原則](https://en.wikipedia.org/wiki/Single_responsibility_principle),它的意思是:在我們的理想中,一個 component應該只負責做一件事情。如果這個 component 最後變大了,你就需要再將它分成數個更小的 subcomponent 。 -<<<<<<< HEAD -由於你常常會展示 JSON 的資料模型給使用者,你會發現,如果你的模式是正確地被建立的話,你的 UI(以及你的 component 結構)就會很好的對應起來。這是因為 UI 和資料模型通常是遵守相同的*資訊架構*,這意味著將你的 UI 拆成 component 通常是相當容易的。只要將 UI 分解成數個 component,每一個都明確代表著你的資料模型中的某一部份即可。 -======= 由於你常常會展示 JSON 的資料模型給使用者,你會發現,如果你的模式是正確地被建立的話,你的 UI(以及你的 component 結構)會很好的相互對應。這是因為 UI 和資料模型通常是遵守同樣的*資訊架構*,這意味著將你的 UI 拆成 component 通常是相當容易的。只要將 UI 分解成數個 component,每一個都明確代表著你的資料模型中的某一部份即可。 ->>>>>>> Fix typos ![Component 架構圖](../images/blog/thinking-in-react-components.png)