From 59dcb6f60261172b9c9892a35061470c94ad0f8e Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Fri, 5 Apr 2019 13:23:52 +0300 Subject: [PATCH 01/36] translate thinking in react --- content/docs/thinking-in-react.md | 162 +++++++++++++++--------------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 7b2e2e7e6..3a1fb241e 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -1,148 +1,148 @@ --- id: thinking-in-react -title: Thinking in React +title: Tư duy trong React permalink: docs/thinking-in-react.html redirect_from: - - 'blog/2013/11/05/thinking-in-react.html' - - 'docs/thinking-in-react-zh-CN.html' +- 'blog/2013/11/05/thinking-in-react.html' +- 'docs/thinking-in-react-zh-CN.html' 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. +Theo ý kiến cá nhân, React là cách tốt nhất để xây dựng những ứng dụng Web lớn một cách nhanh chóng. Nó được sử dụng rộng rãi cho Facebook và 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. +Một trong những điểm tuyệt vời của React là nó giúp bạn phát triển lối tư duy về cách xây dựng các ứng dụng. Trong tài liệu này, chúng tôi sẽ hướng dẫn bạn quy trình xây dựng một bảng dữ liệu tìm kiếm sản phẩm bằng React. -## Start With A Mock {#start-with-a-mock} +## Bắt đầu với Mock {#start-with-a-mock} -Imagine that we already have a JSON API and a mock from our designer. The mock looks like this: +Tưởng tượng rằng chúng ta có một API và một bản mock từ người thiết kế. Bản mock trông như sau: ![Mockup](../images/blog/thinking-in-react-mock.png) -Our JSON API returns some data that looks like this: +Dữ liệu trả về từ JSON API như sau: ``` [ - {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, - {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, - {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, - {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, - {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, - {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} +{category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, +{category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, +{category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, +{category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, +{category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, +{category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} ]; ``` -## Step 1: Break The UI Into A Component Hierarchy {#step-1-break-the-ui-into-a-component-hierarchy} +## Bước 1: Chia giao diện người dùng thành các 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! +Điều đầu tiên cần làm là khoanh tròn và đặt tên cho tất cả các component (và cả component con) trong bản mock. Thảo luận với người thiết kế, họ có thể đã đặt tên cho chúng. Tên của các layer trong bản vẽ photoshop có thể thành tên các react component của bạn! -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. +Nhưng làm thế nào để chia nhỏ giao diện thành những component? Hãy sử dụng những quy tắc khi bạn quyết định nên viết thêm một hàm hay tạo ra một object mới. Một trong những quy tắc đó là [quy tắc đơn nhiệm](https://en.wikipedia.org/wiki/Single_responsibility_principle) -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. +Vì mô hình dữ liệu thường hiển thị dưới dạng chuỗi JSON, nếu mô hình của bạn được thực hiện đúng, giao diện người dùng (và vì thế cấu trúc component) sẽ hoàn toàn tương thích. Đó là bởi vì giao diện người dùng và mô hình dữ liệu thường có xu hướng tuân thủ cùng một kiểu *thông tin kiến trúc*, có nghĩa rằng bạn sẽ không phải dành nhiều thời gian cho việc chia nhỏ giao diện người dùng. Mỗi component sẽ tượng trưng cho một phần mô hình dữ liệu. -![Component diagram](../images/blog/thinking-in-react-components.png) +![Sơ đồ 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. +Có năm component trong ứng dựng, dữ liệu mà component hiển thị sẽ được in nghiêng - 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` (orange):** chứa toàn bộ cả ứng dụng +2. **`SearchBar` (blue):** nơi *người dùng nhập dữ liệu* +3. **`ProductTable` (green):** lọc và hiển thị *kết quả* dựa trên *dữ liệu đầu vào* +4. **`ProductCategoryRow` (turquoise):** hiển thị trương mục theo *thể loại* +5. **`ProductRow` (red):** hiển thị *sản phẩm* theo từng dòng -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. +Nhìn vào `ProductTable`, bạn sẽ thấy rằng tiêu đề cuả bảng (bao gồm những tiêu đề như "Name" và "Price") không được chia nhỏ thành các component. Đây là một tuỳ chọn mang tính cá nhânnhân, đã có những cuộc thảo luận về vấn đề này. Trong ví dụ, chúng ta để nó như là một phần của `ProductTable` bởi vì nó là một phần khi hiển thị *bảng dữ liệu* thuộc về `ProductTable`. Tuy nhiên, nếu như phần tiêu đề trở nên phức tạp (ví dụ nếu chúng ta thêm chức năng sắp xếp phân loại), thì tất nhiên sẽ hơp lí hơn khi có component `ProductTableHeader` cho phần tiêu đề. -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: +Bây giờ khi xác định các component trong bản mock, hãy sắp xếp nó theo một hệ thống phân chia cấp bậc. Những component cùng nằm bên trong một component trong bản mock thì nó nên là component con trong hệ thống cấp bậc: - * `FilterableProductTable` - * `SearchBar` - * `ProductTable` - * `ProductCategoryRow` - * `ProductRow` +* `FilterableProductTable` +* `SearchBar` +* `ProductTable` +* `ProductCategoryRow` +* `ProductRow` -## Step 2: Build A Static Version in React {#step-2-build-a-static-version-in-react} +## Bước 2: Xây dựng một bản tĩnh trong React {#step-2-build-a-static-version-in-react} -

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

+

Xem Pen Tư duy trong React: bước 2 trên CodePen.

-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. +Bây giờ bạn đã có hệ thống cấp bậc cho component của bạn, đã đến lúc hoàn thiện ứng dụng. Cách dễ nhất là xây dựng một phiên bản để hiển thị mô hình dữ liệu và giao diện người dùng của bạn mà không tương tác với nhau. Đây là cách tốt nhất để phân chia các tiến trình này bởi vì xây dựng một phiên bản tĩnh yêu cầu rất nhiều công sức để đánh máy thủ công mà không cần suy nghĩ. Nhưng khi thêm chức năng tương tác thì nó lại yêu cầu ra theo hướng ngược lại, chúng ta sẽ xem xét tại sao lại như vậy. -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. +Để xây dựng một phiên bản tĩnh của ứng dụng để hiển thị mô hình dữ liệu, bạn nên tạo ra các component tái sử dụng và truyền dữ liệu vào bằng *props*. *props* là cách để truyền dữ liệu từ component cha sang component con. Nếu như bạn đã làm quen với khái niệm của *state*, **đừng sử dụng state** để xây dựng một phiên bản tĩnh. State được sử dụng trong trường hợp cần tương tác, khi dữ liệu thay đổi theo thời gian. Bởi vì đây là phiên bản tĩnh của ứng dụng nên bạn sẽ không cần nó. -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. +Bạn có thể tạo ra theo chiều từ trên xuống dưới hoặc ngược lại. Điều đó có nghĩa, bạn có thể bắt đầu với những component ở phía trên của hệ thống phân chia cấp bậc (ví dụ bắt đầu với `FilterableProductTable`) hoặc với những component con của nó (`ProductRow`). Trong những ví dụ đơn giản, thường thì nó sẽ đi theo chiều từ trên xuống dưới, và trong những dự án lớn thường sẽ dễ dàng hơn nếu làm theo hướng ngược lại và song song là viết test cho nó. -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. +Sau khi kết thúc, bạn sẽ có những thư viện có thể tái sử dụng để hiển thị mô hình dữ liệu. Những component sẽ chỉ có hàm `render()` vì đây là phiên bản tĩnh. Component ở phía trên của hệ thống phân chia cấp bậc (`FilterableProductTable`) sẽ nhận kiểu dữ liệu bằng prop. Nếu dữ liệu được thay đổi và hàm `ReactDOM.render()` được gọi lại, thì giao diện người dùng sẽ được cập nhật. Điều này sẽ giúp cho ta hiểu làm thế nào giao diện người dùng được cập nhật dễ dàng hơn và dữ liệu bị thay đổi ở đâu bởi vì nó không bị phức tạp hoá. React **luồng dữ liệu một chiều** (hay còn gọi *ràng buộc một chiều*) giữ cho mọi thứ được phân chia theo module và nhanh gọn. -Simply refer to the [React docs](/docs/) if you need help executing this step. +Tham khảo [tài liệu React](/docs/) nếu như bạn cần trợ giúp để thực hiện bước này. -### A Brief Interlude: Props vs State {#a-brief-interlude-props-vs-state} +### Bản tóm tắt ngắn gọn: Props và 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. +Có hai kiểu "mô hình" dữ liệu trong React: props và state. Hãy chắc chắn rằng bạn hiểu sự khác biệt giữa chúng, tham khảo thêm tại [tài liệu chính thức về React](/docs/interactivity-and-dynamic-uis.html). -## Step 3: Identify The Minimal (but complete) Representation Of UI State {#step-3-identify-the-minimal-but-complete-representation-of-ui-state} +## Bước 3: Xác định các trạng thái hoàn chỉnh nhỏ nhất của giao diện người dùng {#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**. +Để làm cho giao diện người dùng tương tác, bạn cần có khả năng để kích hoạt những thay đổi đối với mô hình dữ liệu cơ bản. React làm điều đó một cách dễ dàng bằng **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. +Để xây dựng ứng dụng của bạn một cách chuẩn xác, đầu tiên cần suy nghĩ về một tập hợp tối thiểu các state có khả năng thay đổi trong ứng dựng. Trọng điểm là [DRY: *Không lập lại*](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) Xác định tập hợp này và tính toán những yêu cầu khác. Ví dụ, bạn tạo ra một danh sách TODO, không nên dùng state để đếm phần tử của mảng TODO. Thay vào đó khi in ra số lượng TODO, chỉ cần tính độ dài của mảng TODO. -Think of all of the pieces of data in our example application. We have: +Suy tính về các thành phần dữ liệu trong ví dụ ứng dựng, nó bao gồm: - * The original list of products - * The search text the user has entered - * The value of the checkbox - * The filtered list of products +* Danh sách gốc các sản phẩm +* Từ khoá tìm kiếm từ phía người dùng +* Giá trị của checkbox +* Danh sách sản phẩm sau khi phân loại -Let's go through each one and figure out which one is state. Simply ask three questions about each piece of data: +Hãy cùng tìm hiểu xem thành phần nào là trạng thái bằng cách đặt ra 3 câu hổi cho mỗi phần: - 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. Có phải nó được truyền từ component cha qua props không? Nếu có thì nó có thể không phải là state. +2. Dữ liệu có thay đổi không? nếu không thì nó không phải là state. +3. Bạn có thể tính toán nó từ các state hay props khác trong component cuả bạn không? nếu có thì nó không phải là 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. +Danh sách gốc của sản phẩm được truyền vào thông qua props, vậy nó không phải state. Từ khoá tìm kiếm và checkbox có vẻ là state bởi vì chúng sẽ bị thay đổi và không thể tính toán dựa trên phần còn lại. Cuối cùng, danh sách phân loại sản phẩm không phải là state bởi vì nó có thể được tìm ra dựa vào danh sách gốc với từ khoá tìm kiếm và giá trị của checkbox. -So finally, our state is: +Cuối cùng, state của chúng ta là: - * The search text the user has entered - * The value of the checkbox +* Từ khoá tìm kiếm người dùng nhập vào +* Giá trị của checkbox -## Step 4: Identify Where Your State Should Live {#step-4-identify-where-your-state-should-live} +## Bước 4: Xác định state của bạn ở đâu {#step-4-identify-where-your-state-should-live} -

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

+

Xem ví dụ Pen Tư duy trong React: Bước 4 on CodePen.

-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. +Chúng ta đã xác định được tập hợp tối thiểu các state của ứng dụng . Tiếp theo chúng ta cần suy nghĩ component nào sẽ thay đổi, hoặc sở hữu, state này. -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: +Lưu ý: React truyền dữ liệu một chiều xuống trong hệ thống phân chia cấp bậc component. Nó có thể không rõ ràng ngay lập tức rằng component nào nên có state của riêng nó. **Đây thường là phần thử thách nhất cho những người mới bắt đầu để hiểu,** hãy theo những bước sau để tìm hiểu: -For each piece of state in your application: +Cho mỗi phần của state trong ứng dụng của bạn: - * 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. +* Xác định tất cả các component sẽ hiển thị dựa trên state. +* Tìm ra một component cha ( component ở phía trên các component cần state ở trong hệ thống phân chia cấp bậc). +* Hoặc là component cha hay component khác ở phía trên nên giữ state.¨ +* Nếu bạn không thể tìm ra component hợp lí, thì hãy tạo ra một component mới nắm giữ state và thêm nó vào trong hệ thông phân chia cấp bậc ở phía trên component cha. -Let's run through this strategy for our application: +Hãy cùng điểm lại kế hoạch cho ứng dụng của chúng ta: - * `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` cần để lọc danh sách các sản phẩm dựa trên state và `SearchBar` cần hiển thị từ khoá tìm kiếm và state đã được lựa chọn. +* Component cha là `FilterableProductTable`. +* Theo lí thuyết thì từ khoá tìm kiếm và giá trị lưạ chọn nên nằm trong `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`. +Vậy chúng ta đã quyết định rằng state của chúng ta sẽ nằm trong `FilterableProductTable`. Đầu tiên, thêm một thuộc tính của instance `this.state = {filterText: '', inStockOnly: false}` vào hàm khởi tạo của `FilterableProductTable` để khai báo trạng thái ban đầu của ứng dụng. Sau đó, truyền các tham số `filterText` và `inStockOnly` tới `ProductTable` và `SearchBar` như là một prop. Cuối cùng, sử dụng những props này để lọc những hàng ở trong `ProductTable` và gán những giá trị vào các trường của form trong `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. +Bạn có thể bắt đầu thấy ứng dụng của bạn hoạt động ra sao: gán `"ball"` vào `filterText` và refresh lại ứng dụng. Bạn sẽ thấy rằng các dữ liệu của bảng được cập nhật chính xác. -## Step 5: Add Inverse Data Flow {#step-5-add-inverse-data-flow} +## Bước 5: Cập nhật dữ liệu theo chiều ngược lại {#step-5-add-inverse-data-flow} -

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

+

Xem Pen Tư duy trong React: Bước 5 tại CodePen.

-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`. +Cho đến giờ, chúng ta đã xây dựng một ứng dụng để hiển thị chính xác các giá trị của props và state từ trên xuống dưới trong hệ thống phân chia cấp bậc. Giờ là lúc để làm cho luồng dữ liệu có thể vận chuyển theo hướng ngược lại: những component form ở phía dưới cần cập nhật trạng thái cho `FilterableProductTable`. -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 làm cho luồng dữ liệu trở nên rõ ràng và dễ hiểu hơn chương trình của bạn hoạt động ra sao, nhưng nó cũng yêu cầu gõ nhiều hơn so với kiểu binding dữ liệu hai chiều truyền thống. -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`. +Nếu bạn thử gõ hoặc lựa chọn giá trị trong ví dụ hiện thời, bạn sẽ thấy rằng React bỏ qua những giá trị đầu vào này. Điều này sảy ra có chủ ý, vì chúng ta gán `value` prop của `input` luôn luôn bằng với `state` truyền từ `FilterableProductTable`. -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. +Hãy nghĩ xem chúng ta muốn thực hiện điều gì. Chúng ta muốn chắc chắn rằng khi nào người dùng thay đổi form, chúng ta cập nhật state dựa trên dữ liệu đầu vào. Vì những component chỉ nên cập nhật state cuả chúng, `FilterableProductTable` sẽ truyền vào callbacks tới `SearchBar` để kích hoạt mỗi khi dữ liệu cần cập nhật. Chúng ta có thể sử dụng sự kiện `onChange` trong input để nhận được thông báo. Callbacks truyền xuống bởi `FilterableProductTable` sẽ gọi hàm `setState()`, và ứng dụng sẽ được cập nhật. -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. +Mặc dù nó nghe thì phức tạp, nhưng thật ra chỉ cần vài dòng lệnh. Và nó chỉ ra rất rõ ràng luồng dữ liệu truyền đi trong ứng dụng. -## And That's It {#and-thats-it} +## Và kết thúc {#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. :) +Hy vọng rằng nó sẽ cho bạn một ý tưởng về cách tư duy khi tạo ra những component và ứng dụng với React. Trong khi nó cần gõ nhiều hơn bạn từng làm, nhớ rằng code này rất rõ ràng và dễ đọc. Khi bạn bắt đầu xây dựng những thư viện component lớn, bạn sẽ thấy sự hữu dụng khi đọc những code module hoá và rõ ràng, với code tái sử dụng số lượng code sẽ giảm xuống. From 28f6cec2ae25ffb6b9706517af78b5bb1fdf1f43 Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Fri, 5 Apr 2019 13:32:14 +0300 Subject: [PATCH 02/36] fixed indentation --- content/docs/thinking-in-react.md | 68 +++++++++++++++---------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 3a1fb241e..04b2e03ac 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -3,8 +3,8 @@ id: thinking-in-react title: Tư duy trong React permalink: docs/thinking-in-react.html redirect_from: -- 'blog/2013/11/05/thinking-in-react.html' -- 'docs/thinking-in-react-zh-CN.html' + - 'blog/2013/11/05/thinking-in-react.html' + - 'docs/thinking-in-react-zh-CN.html' prev: composition-vs-inheritance.html --- @@ -22,12 +22,12 @@ Dữ liệu trả về từ JSON API như sau: ``` [ -{category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, -{category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, -{category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, -{category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, -{category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, -{category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} + {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"}, + {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"}, + {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"}, + {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"}, + {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"}, + {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"} ]; ``` @@ -43,21 +43,21 @@ Vì mô hình dữ liệu thường hiển thị dưới dạng chuỗi JSON, n Có năm component trong ứng dựng, dữ liệu mà component hiển thị sẽ được in nghiêng -1. **`FilterableProductTable` (orange):** chứa toàn bộ cả ứng dụng -2. **`SearchBar` (blue):** nơi *người dùng nhập dữ liệu* -3. **`ProductTable` (green):** lọc và hiển thị *kết quả* dựa trên *dữ liệu đầu vào* -4. **`ProductCategoryRow` (turquoise):** hiển thị trương mục theo *thể loại* -5. **`ProductRow` (red):** hiển thị *sản phẩm* theo từng dòng + 1. **`FilterableProductTable` (orange):** chứa toàn bộ cả ứng dụng + 2. **`SearchBar` (blue):** nơi *người dùng nhập dữ liệu* + 3. **`ProductTable` (green):** lọc và hiển thị *kết quả* dựa trên *dữ liệu đầu vào* + 4. **`ProductCategoryRow` (turquoise):** hiển thị trương mục theo *thể loại* + 5. **`ProductRow` (red):** hiển thị *sản phẩm* theo từng dòng Nhìn vào `ProductTable`, bạn sẽ thấy rằng tiêu đề cuả bảng (bao gồm những tiêu đề như "Name" và "Price") không được chia nhỏ thành các component. Đây là một tuỳ chọn mang tính cá nhânnhân, đã có những cuộc thảo luận về vấn đề này. Trong ví dụ, chúng ta để nó như là một phần của `ProductTable` bởi vì nó là một phần khi hiển thị *bảng dữ liệu* thuộc về `ProductTable`. Tuy nhiên, nếu như phần tiêu đề trở nên phức tạp (ví dụ nếu chúng ta thêm chức năng sắp xếp phân loại), thì tất nhiên sẽ hơp lí hơn khi có component `ProductTableHeader` cho phần tiêu đề. Bây giờ khi xác định các component trong bản mock, hãy sắp xếp nó theo một hệ thống phân chia cấp bậc. Những component cùng nằm bên trong một component trong bản mock thì nó nên là component con trong hệ thống cấp bậc: -* `FilterableProductTable` -* `SearchBar` -* `ProductTable` -* `ProductCategoryRow` -* `ProductRow` + * `FilterableProductTable` + * `SearchBar` + * `ProductTable` + * `ProductCategoryRow` + * `ProductRow` ## Bước 2: Xây dựng một bản tĩnh trong React {#step-2-build-a-static-version-in-react} @@ -86,23 +86,23 @@ Có hai kiểu "mô hình" dữ liệu trong React: props và state. Hãy chắc Suy tính về các thành phần dữ liệu trong ví dụ ứng dựng, nó bao gồm: -* Danh sách gốc các sản phẩm -* Từ khoá tìm kiếm từ phía người dùng -* Giá trị của checkbox -* Danh sách sản phẩm sau khi phân loại + * Danh sách gốc các sản phẩm + * Từ khoá tìm kiếm từ phía người dùng + * Giá trị của checkbox + * Danh sách sản phẩm sau khi phân loại Hãy cùng tìm hiểu xem thành phần nào là trạng thái bằng cách đặt ra 3 câu hổi cho mỗi phần: -1. Có phải nó được truyền từ component cha qua props không? Nếu có thì nó có thể không phải là state. -2. Dữ liệu có thay đổi không? nếu không thì nó không phải là state. -3. Bạn có thể tính toán nó từ các state hay props khác trong component cuả bạn không? nếu có thì nó không phải là state. + 1. Có phải nó được truyền từ component cha qua props không? Nếu có thì nó có thể không phải là state. + 2. Dữ liệu có thay đổi không? nếu không thì nó không phải là state. + 3. Bạn có thể tính toán nó từ các state hay props khác trong component cuả bạn không? nếu có thì nó không phải là state. Danh sách gốc của sản phẩm được truyền vào thông qua props, vậy nó không phải state. Từ khoá tìm kiếm và checkbox có vẻ là state bởi vì chúng sẽ bị thay đổi và không thể tính toán dựa trên phần còn lại. Cuối cùng, danh sách phân loại sản phẩm không phải là state bởi vì nó có thể được tìm ra dựa vào danh sách gốc với từ khoá tìm kiếm và giá trị của checkbox. Cuối cùng, state của chúng ta là: -* Từ khoá tìm kiếm người dùng nhập vào -* Giá trị của checkbox + * Từ khoá tìm kiếm người dùng nhập vào + * Giá trị của checkbox ## Bước 4: Xác định state của bạn ở đâu {#step-4-identify-where-your-state-should-live} @@ -114,16 +114,16 @@ Lưu ý: React truyền dữ liệu một chiều xuống trong hệ thống ph Cho mỗi phần của state trong ứng dụng của bạn: -* Xác định tất cả các component sẽ hiển thị dựa trên state. -* Tìm ra một component cha ( component ở phía trên các component cần state ở trong hệ thống phân chia cấp bậc). -* Hoặc là component cha hay component khác ở phía trên nên giữ state.¨ -* Nếu bạn không thể tìm ra component hợp lí, thì hãy tạo ra một component mới nắm giữ state và thêm nó vào trong hệ thông phân chia cấp bậc ở phía trên component cha. + * Xác định tất cả các component sẽ hiển thị dựa trên state. + * Tìm ra một component cha ( component ở phía trên các component cần state ở trong hệ thống phân chia cấp bậc). + * Hoặc là component cha hay component khác ở phía trên nên giữ state.¨ + * Nếu bạn không thể tìm ra component hợp lí, thì hãy tạo ra một component mới nắm giữ state và thêm nó vào trong hệ thông phân chia cấp bậc ở phía trên component cha. Hãy cùng điểm lại kế hoạch cho ứng dụng của chúng ta: -* `ProductTable` cần để lọc danh sách các sản phẩm dựa trên state và `SearchBar` cần hiển thị từ khoá tìm kiếm và state đã được lựa chọn. -* Component cha là `FilterableProductTable`. -* Theo lí thuyết thì từ khoá tìm kiếm và giá trị lưạ chọn nên nằm trong `FilterableProductTable`. + * `ProductTable` cần lọc danh sách các sản phẩm dựa trên state và `SearchBar` cần hiển thị từ khoá tìm kiếm và state đã được lựa chọn. + * Component cha là `FilterableProductTable`. + * Theo lí thuyết thì từ khoá tìm kiếm và giá trị lưạ chọn nên nằm trong `FilterableProductTable`. Vậy chúng ta đã quyết định rằng state của chúng ta sẽ nằm trong `FilterableProductTable`. Đầu tiên, thêm một thuộc tính của instance `this.state = {filterText: '', inStockOnly: false}` vào hàm khởi tạo của `FilterableProductTable` để khai báo trạng thái ban đầu của ứng dụng. Sau đó, truyền các tham số `filterText` và `inStockOnly` tới `ProductTable` và `SearchBar` như là một prop. Cuối cùng, sử dụng những props này để lọc những hàng ở trong `ProductTable` và gán những giá trị vào các trường của form trong `SearchBar`. From 9c7b6ad7b978153d3729973ea8ae8d671800af7a Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Fri, 5 Apr 2019 13:37:59 +0300 Subject: [PATCH 03/36] improve translation --- 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 04b2e03ac..0065a9434 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -145,4 +145,4 @@ Mặc dù nó nghe thì phức tạp, nhưng thật ra chỉ cần vài dòng l ## Và kết thúc {#and-thats-it} -Hy vọng rằng nó sẽ cho bạn một ý tưởng về cách tư duy khi tạo ra những component và ứng dụng với React. Trong khi nó cần gõ nhiều hơn bạn từng làm, nhớ rằng code này rất rõ ràng và dễ đọc. Khi bạn bắt đầu xây dựng những thư viện component lớn, bạn sẽ thấy sự hữu dụng khi đọc những code module hoá và rõ ràng, với code tái sử dụng số lượng code sẽ giảm xuống. +Hy vọng rằng nó sẽ cho bạn một ý tưởng về cách tư duy khi tạo ra những component và ứng dụng với React. Trong khi nó yêu cầu phải gõ nhiều hơn bạn từng làm, nhưng code này rất rõ ràng và dễ đọc. Khi bạn bắt đầu xây dựng những thư viện component lớn, bạn sẽ thấy sự hữu dụng khi đọc những code module hoá và rõ ràng, thêm nữa số lượng code sẽ giảm xuống khi code được tái sử dụng . From 2efa4278dab9016b959c27a883af4ed8454ee7fe Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Fri, 5 Apr 2019 13:44:52 +0300 Subject: [PATCH 04/36] Update translate --- 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 0065a9434..f544deb7a 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -141,7 +141,7 @@ Nếu bạn thử gõ hoặc lựa chọn giá trị trong ví dụ hiện thờ Hãy nghĩ xem chúng ta muốn thực hiện điều gì. Chúng ta muốn chắc chắn rằng khi nào người dùng thay đổi form, chúng ta cập nhật state dựa trên dữ liệu đầu vào. Vì những component chỉ nên cập nhật state cuả chúng, `FilterableProductTable` sẽ truyền vào callbacks tới `SearchBar` để kích hoạt mỗi khi dữ liệu cần cập nhật. Chúng ta có thể sử dụng sự kiện `onChange` trong input để nhận được thông báo. Callbacks truyền xuống bởi `FilterableProductTable` sẽ gọi hàm `setState()`, và ứng dụng sẽ được cập nhật. -Mặc dù nó nghe thì phức tạp, nhưng thật ra chỉ cần vài dòng lệnh. Và nó chỉ ra rất rõ ràng luồng dữ liệu truyền đi trong ứng dụng. +Mặc dù nó nghe phức tạp, nhưng thật ra chỉ cần vài dòng lệnh. Và nó chỉ ra rất rõ ràng luồng dữ liệu được truyền đi trong ứng dụng như thế nào. ## Và kết thúc {#and-thats-it} From 7675c5c57d0baf8fd21646e15e512ee7d9b4a01a Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Tue, 9 Apr 2019 09:28:57 +0300 Subject: [PATCH 05/36] fix typo --- content/docs/thinking-in-react.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index f544deb7a..09d65f1db 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -14,7 +14,7 @@ Một trong những điểm tuyệt vời của React là nó giúp bạn phát ## Bắt đầu với Mock {#start-with-a-mock} -Tưởng tượng rằng chúng ta có một API và một bản mock từ người thiết kế. Bản mock trông như sau: +Tưởng tượng rằng chúng ta có một JSON API và một bản mock từ người thiết kế. Bản mock trông như sau: ![Mockup](../images/blog/thinking-in-react-mock.png) @@ -41,7 +41,7 @@ Vì mô hình dữ liệu thường hiển thị dưới dạng chuỗi JSON, n ![Sơ đồ Component](../images/blog/thinking-in-react-components.png) -Có năm component trong ứng dựng, dữ liệu mà component hiển thị sẽ được in nghiêng +Trong ứng dụng đơn giản dưới đây, bạn sẽ thấy chúng ta có 5 component, dữ liệu mà mỗi component hiển thị sẽ được in nghiêng 1. **`FilterableProductTable` (orange):** chứa toàn bộ cả ứng dụng 2. **`SearchBar` (blue):** nơi *người dùng nhập dữ liệu* @@ -49,7 +49,7 @@ Có năm component trong ứng dựng, dữ liệu mà component hiển thị s 4. **`ProductCategoryRow` (turquoise):** hiển thị trương mục theo *thể loại* 5. **`ProductRow` (red):** hiển thị *sản phẩm* theo từng dòng -Nhìn vào `ProductTable`, bạn sẽ thấy rằng tiêu đề cuả bảng (bao gồm những tiêu đề như "Name" và "Price") không được chia nhỏ thành các component. Đây là một tuỳ chọn mang tính cá nhânnhân, đã có những cuộc thảo luận về vấn đề này. Trong ví dụ, chúng ta để nó như là một phần của `ProductTable` bởi vì nó là một phần khi hiển thị *bảng dữ liệu* thuộc về `ProductTable`. Tuy nhiên, nếu như phần tiêu đề trở nên phức tạp (ví dụ nếu chúng ta thêm chức năng sắp xếp phân loại), thì tất nhiên sẽ hơp lí hơn khi có component `ProductTableHeader` cho phần tiêu đề. +Nhìn vào `ProductTable`, bạn sẽ thấy rằng tiêu đề cuả bảng (bao gồm những tiêu đề như "Name" và "Price") không được chia nhỏ thành các component. Đây là một tuỳ chọn mang tính cá nhân, đã có những cuộc thảo luận về vấn đề này. Trong ví dụ, chúng ta để nó như là một phần của `ProductTable` bởi vì nó là một phần khi hiển thị *bảng dữ liệu* thuộc về `ProductTable`. Tuy nhiên, nếu như phần tiêu đề trở nên phức tạp (ví dụ nếu chúng ta thêm chức năng sắp xếp phân loại), thì tất nhiên sẽ hơp lí hơn khi có component `ProductTableHeader` cho phần tiêu đề. Bây giờ khi xác định các component trong bản mock, hãy sắp xếp nó theo một hệ thống phân chia cấp bậc. Những component cùng nằm bên trong một component trong bản mock thì nó nên là component con trong hệ thống cấp bậc: From 1b6d257eda353a6b3462b2813996c237e6f2f22b Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Tue, 9 Apr 2019 09:32:33 +0300 Subject: [PATCH 06/36] add more change --- content/docs/thinking-in-react.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/docs/thinking-in-react.md b/content/docs/thinking-in-react.md index 09d65f1db..8fa2530e4 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -44,8 +44,8 @@ Vì mô hình dữ liệu thường hiển thị dưới dạng chuỗi JSON, n Trong ứng dụng đơn giản dưới đây, bạn sẽ thấy chúng ta có 5 component, dữ liệu mà mỗi component hiển thị sẽ được in nghiêng 1. **`FilterableProductTable` (orange):** chứa toàn bộ cả ứng dụng - 2. **`SearchBar` (blue):** nơi *người dùng nhập dữ liệu* - 3. **`ProductTable` (green):** lọc và hiển thị *kết quả* dựa trên *dữ liệu đầu vào* + 2. **`SearchBar` (blue):** nơi *người dùng nhập từ khoá tìm kiếm* + 3. **`ProductTable` (green):** lọc và hiển thị *kết quả* dựa trên *từ khoá tìm kiếm* 4. **`ProductCategoryRow` (turquoise):** hiển thị trương mục theo *thể loại* 5. **`ProductRow` (red):** hiển thị *sản phẩm* theo từng dòng From 74bb3b4ef04a4b5711051e178cf9e37fcbfb4309 Mon Sep 17 00:00:00 2001 From: Tran Quoc Cuong Date: Wed, 10 Apr 2019 09:49:52 +0300 Subject: [PATCH 07/36] Improve translate --- 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 8fa2530e4..59e4c192e 100644 --- a/content/docs/thinking-in-react.md +++ b/content/docs/thinking-in-react.md @@ -35,7 +35,7 @@ Dữ liệu trả về từ JSON API như sau: Điều đầu tiên cần làm là khoanh tròn và đặt tên cho tất cả các component (và cả component con) trong bản mock. Thảo luận với người thiết kế, họ có thể đã đặt tên cho chúng. Tên của các layer trong bản vẽ photoshop có thể thành tên các react component của bạn! -Nhưng làm thế nào để chia nhỏ giao diện thành những component? Hãy sử dụng những quy tắc khi bạn quyết định nên viết thêm một hàm hay tạo ra một object mới. Một trong những quy tắc đó là [quy tắc đơn nhiệm](https://en.wikipedia.org/wiki/Single_responsibility_principle) +Nhưng làm thế nào để chia nhỏ giao diện thành những component? Hãy sử dụng những kỹ thuật khi quyết định nên viết thêm một hàm hay tạo ra một object mới. Một trong những kỹ thuật đó là [nguyên tắc đơn nhiệm](https://en.wikipedia.org/wiki/Single_responsibility_principle) Vì mô hình dữ liệu thường hiển thị dưới dạng chuỗi JSON, nếu mô hình của bạn được thực hiện đúng, giao diện người dùng (và vì thế cấu trúc component) sẽ hoàn toàn tương thích. Đó là bởi vì giao diện người dùng và mô hình dữ liệu thường có xu hướng tuân thủ cùng một kiểu *thông tin kiến trúc*, có nghĩa rằng bạn sẽ không phải dành nhiều thời gian cho việc chia nhỏ giao diện người dùng. Mỗi component sẽ tượng trưng cho một phần mô hình dữ liệu. From 1bacaa531c9c8583b10eecf213d778153e98257e Mon Sep 17 00:00:00 2001 From: TuanTV Date: Thu, 11 Apr 2019 17:59:30 +0700 Subject: [PATCH 08/36] translate vietnamese home page, header, footer --- content/community/nav.yml | 4 ++-- content/docs/nav.yml | 10 +++++----- .../a-component-using-external-plugins.md | 4 ++-- content/home/examples/a-simple-component.md | 6 +++--- content/home/examples/a-stateful-component.md | 2 +- content/home/examples/an-application.md | 4 ++-- content/home/marketing/component-based.md | 4 ++-- content/home/marketing/declarative.md | 4 ++-- .../home/marketing/learn-once-write-anywhere.md | 6 +++--- src/components/LayoutFooter/Footer.js | 16 ++++++++-------- src/components/LayoutHeader/DocSearch.js | 2 +- src/components/LayoutHeader/Header.js | 9 +++++---- .../TitleAndMetaTags/TitleAndMetaTags.js | 2 +- src/pages/404.js | 10 +++++----- src/pages/index.js | 12 ++++++------ 15 files changed, 48 insertions(+), 47 deletions(-) diff --git a/content/community/nav.yml b/content/community/nav.yml index 0f59b80a0..44d1b29a6 100644 --- a/content/community/nav.yml +++ b/content/community/nav.yml @@ -1,4 +1,4 @@ -- title: Community Resources +- title: Nguồn cộng đồng items: - id: support title: Support @@ -18,7 +18,7 @@ title: Videos - id: external-resources title: External Resources -- title: Tools +- title: Công cụ items: - id: debugging-tools title: Debugging diff --git a/content/docs/nav.yml b/content/docs/nav.yml index 2eafe8803..eff955a4e 100644 --- a/content/docs/nav.yml +++ b/content/docs/nav.yml @@ -1,4 +1,4 @@ -- title: Installation +- title: Cài đặt items: - id: getting-started title: Getting Started @@ -8,7 +8,7 @@ title: Create a New React App - id: cdn-links title: CDN Links -- title: Main Concepts +- title: Khái niệm isOrdered: true items: - id: hello-world @@ -35,7 +35,7 @@ title: Composition vs Inheritance - id: thinking-in-react title: Thinking In React -- title: Advanced Guides +- title: Hướng dẫn nâng cao items: - id: accessibility title: Accessibility @@ -79,7 +79,7 @@ title: Uncontrolled Components - id: web-components title: Web Components -- title: API Reference +- title: API Tham khảo items: - id: react-api title: React @@ -123,7 +123,7 @@ title: Tham chiếu Hooks API - id: hooks-faq title: Hooks FAQ -- title: Contributing +- title: Đóng góp items: - id: how-to-contribute title: How to Contribute diff --git a/content/home/examples/a-component-using-external-plugins.md b/content/home/examples/a-component-using-external-plugins.md index 1c50c8718..1fc156ecd 100644 --- a/content/home/examples/a-component-using-external-plugins.md +++ b/content/home/examples/a-component-using-external-plugins.md @@ -1,7 +1,7 @@ --- -title: A Component Using External Plugins +title: Một thành phần sử dụng plugins bên ngoài order: 3 domid: markdown-example --- -React allows you to interface with other libraries and frameworks. This example uses **remarkable**, an external Markdown library, to convert the `