Tạo thành phần giao diện người dùng javascript
Ghi chú. Nếu trước đây bạn đã cài đặt 29 trên toàn cầu, bạn nên gỡ cài đặt gói này để đảm bảo npx luôn sử dụng phiên bản mới nhất của 29. Để gỡ cài đặt, hãy chạy lệnh này. 31 Show
Chạy ứng dụng ReactChạy lệnh này để di chuyển đến thư mục 32Chạy lệnh này để thực thi ứng dụng React 32Một cửa sổ trình duyệt mới sẽ bật lên với Ứng dụng React mới được tạo của bạn. Nếu không, hãy mở trình duyệt của bạn và nhập ReactDOM.(myElement, document.getElementById('root'));2 vào thanh địa chỉ Kết quả Những gì bạn nên biếtTrước khi bắt đầu với React. JS, bạn nên có kinh nghiệm trung cấp về Bạn cũng nên có một số kinh nghiệm với các tính năng JavaScript mới được giới thiệu trong ECMAScript 6 (ES6), bạn sẽ tìm hiểu về chúng trong chương React ES6 Trong Phần 4. Store, chúng ta đã thấy cách tạo Redux store, gửi các hành động và đọc trạng thái hiện tại. Chúng tôi cũng đã xem xét cách một cửa hàng hoạt động bên trong, cách các công cụ hỗ trợ và phần mềm trung gian cho phép chúng tôi tùy chỉnh cửa hàng với các khả năng bổ sung và cách thêm Redux DevTools để cho chúng tôi biết điều gì đang xảy ra bên trong ứng dụng của mình khi các hành động được gửi đi Trong phần này, chúng tôi sẽ thêm Giao diện người dùng cho ứng dụng việc cần làm của chúng tôi. Chúng ta sẽ xem cách Redux hoạt động với lớp giao diện người dùng một cách tổng thể và chúng ta sẽ đề cập cụ thể cách Redux hoạt động cùng với React Tích hợp Redux với giao diện người dùngRedux là một thư viện JS độc lập. Như chúng ta đã thấy, bạn có thể tạo và sử dụng cửa hàng Redux ngay cả khi bạn chưa thiết lập giao diện người dùng. Điều này cũng có nghĩa là bạn có thể sử dụng Redux với bất kỳ khung giao diện người dùng nào (hoặc thậm chí không có bất kỳ khung giao diện người dùng nào) và sử dụng nó trên cả máy khách và máy chủ. Bạn có thể viết các ứng dụng Redux bằng React, Vue, Angular, Ember, jQuery hoặc vanilla JavaScript Điều đó nói rằng, Redux được thiết kế đặc biệt để hoạt động tốt với React. React cho phép bạn mô tả giao diện người dùng của mình dưới dạng một chức năng của trạng thái của bạn và Redux chứa trạng thái và cập nhật trạng thái đó để đáp ứng với các hành động Do đó, chúng tôi sẽ sử dụng React cho hướng dẫn này khi chúng tôi xây dựng ứng dụng việc cần làm của mình và đề cập đến những điều cơ bản về cách sử dụng React với Redux Trước khi đến phần đó, chúng ta hãy xem nhanh cách Redux tương tác với một lớp giao diện người dùng nói chung Tích hợp giao diện người dùng và Redux cơ bảnSử dụng Redux với bất kỳ lớp giao diện người dùng nào yêu cầu một số bước nhất quán
Hãy quay lại ví dụ về ứng dụng bộ đếm mà chúng ta đã thấy trong Phần 1 và xem nó tuân theo các bước đó như thế nào
Bất kể bạn đang sử dụng lớp giao diện người dùng nào, Redux hoạt động theo cùng một cách với mọi giao diện người dùng. Việc triển khai thực tế thường phức tạp hơn một chút để giúp tối ưu hóa hiệu suất, nhưng mỗi lần thực hiện đều giống nhau Vì Redux là một thư viện riêng biệt, nên có các thư viện "ràng buộc" khác nhau để giúp bạn sử dụng Redux với một khung giao diện người dùng nhất định. Các thư viện liên kết giao diện người dùng đó xử lý chi tiết đăng ký cửa hàng và cập nhật giao diện người dùng một cách hiệu quả khi trạng thái thay đổi, do đó bạn không phải tự viết mã đó Sử dụng Redux với ReactThư viện ràng buộc giao diện người dùng React-Redux chính thức là một gói riêng biệt với lõi Redux. Bạn sẽ cần phải cài đặt thêm
(Nếu bạn không sử dụng npm, bạn có thể lấy bản dựng UMD mới nhất từ unpkg (bản phát triển hoặc bản sản xuất). Bản dựng UMD xuất toàn cầu có tên là 3 nếu bạn thêm nó vào trang của mình thông qua thẻ 4. )Đối với hướng dẫn này, chúng tôi sẽ đề cập đến các mẫu và ví dụ quan trọng nhất mà bạn cần để sử dụng React và Redux cùng nhau, đồng thời xem cách chúng hoạt động trong thực tế như một phần của ứng dụng việc cần làm của chúng tôi thông tinXem tài liệu React-Redux chính thức tại https. //reac-redux. js. org để có hướng dẫn đầy đủ về cách sử dụng Redux và React cùng nhau cũng như tài liệu tham khảo về API React-Redux Thiết kế cây thành phầnGiống như chúng ta dựa trên các yêu cầu, chúng ta cũng có thể thiết kế tập hợp tổng thể các thành phần giao diện người dùng và cách chúng liên quan với nhau trong ứng dụng Dựa trên , tối thiểu chúng ta sẽ cần bộ thành phần này
Ngoài cấu trúc thành phần cơ bản này, chúng ta có thể chia các thành phần theo nhiều cách khác nhau. Ví dụ: thành phần 9 có thể là một thành phần lớn hơn hoặc có thể có nhiều thành phần nhỏ hơn bên trong như 11, 12 và 13. Không có cách nào đúng để phân chia những thứ này và bạn sẽ thấy rằng có thể tốt hơn nếu viết các thành phần lớn hơn hoặc chia mọi thứ thành nhiều thành phần nhỏ hơn tùy thuộc vào tình huống của bạnHiện tại, chúng ta sẽ bắt đầu với danh sách nhỏ các thành phần này để giúp mọi thứ dễ theo dõi hơn. Về lưu ý đó, vì chúng tôi cho rằng bạn đã biết React, nên chúng tôi sẽ bỏ qua chi tiết về cách viết mã bố cục cho các thành phần này và tập trung vào cách thực sự sử dụng thư viện React-Redux trong các thành phần React của bạn. Đây là giao diện người dùng React ban đầu của ứng dụng này trước khi chúng tôi bắt đầu thêm bất kỳ logic nào liên quan đến Redux Đọc trạng thái từ Cửa hàng với // 1) Create a new Redux store with the `createStore` functionconst store = Redux.createStore(counterReducer)// 2) Subscribe to redraw whenever the data changes in the futurestore.subscribe(render)// Our "user interface" is some text in a single HTML elementconst valueEl = document.getElementById('value')// 3) When the subscription callback runs:function render() { // 3.1) Get the current store state const state = store.getState() // 3.2) Extract the data you want const newValue = state.value.toString() // 3.3) Update the UI with the new value valueEl.innerHTML = newValue}// 4) Display the UI with the initial store staterender()// 5) Dispatch actions based on UI inputsdocument.getElementById('increment').addEventListener('click', function () { store.dispatch({ type: 'counter/incremented' })})14Chúng tôi biết rằng chúng tôi cần có khả năng hiển thị danh sách các mục việc cần làm. Hãy bắt đầu bằng cách tạo một thành phần 7 có thể đọc danh sách các công việc cần làm từ cửa hàng, lặp lại chúng và hiển thị một thành phần 8 cho mỗi mục công việcBạn nên làm quen với các hook React như 17, có thể được gọi trong các thành phần hàm React để cấp cho chúng quyền truy cập vào các giá trị trạng thái React. React cũng cho phép chúng ta viết các hook tùy chỉnh, cho phép chúng ta trích xuất các hook có thể tái sử dụng để thêm hành vi của riêng chúng ta lên trên các hook tích hợp của ReactGiống như nhiều thư viện khác, React-Redux bao gồm các móc tùy chỉnh riêng mà bạn có thể sử dụng trong các thành phần của riêng mình. Các hook React-Redux cung cấp cho thành phần React của bạn khả năng nói chuyện với cửa hàng Redux bằng cách đọc trạng thái và gửi hành động Móc React-Redux đầu tiên mà chúng ta sẽ xem xét là , cho phép các thành phần React của bạn đọc dữ liệu từ cửa hàng Redux 14 chấp nhận một chức năng duy nhất mà chúng tôi gọi là chức năng chọn. Bộ chọn là một hàm lấy toàn bộ trạng thái cửa hàng Redux làm đối số, đọc một số giá trị từ trạng thái và trả về kết quả đóVí dụ: chúng tôi biết rằng trạng thái Redux của ứng dụng việc cần làm của chúng tôi giữ mảng các mục việc cần làm là ________ 190. Chúng ta có thể viết một hàm chọn nhỏ trả về mảng todos đó 1Hoặc, có thể chúng tôi muốn tìm hiểu có bao nhiêu việc cần làm hiện được đánh dấu là "đã hoàn thành" 9Vì vậy, bộ chọn có thể trả về các giá trị từ trạng thái lưu trữ Redux và cũng trả về các giá trị dẫn xuất dựa trên trạng thái đó Hãy đọc mảng todos vào thành phần 7 của chúng ta. Đầu tiên, chúng ta sẽ nhập hook 14 từ thư viện 93, sau đó gọi nó với hàm selector làm đối sốsrc/features/todos/TodoList. js 5Lần đầu tiên thành phần 7 kết xuất, hook 14 sẽ gọi 96 và chuyển vào toàn bộ đối tượng trạng thái Redux. Bất cứ điều gì bộ chọn trả về sẽ được móc trả về thành phần của bạn. Vì vậy, 97 trong thành phần của chúng tôi cuối cùng sẽ giữ cùng một mảng 90 bên trong trạng thái cửa hàng Redux của chúng tôiNhưng, điều gì sẽ xảy ra nếu chúng ta gửi một hành động như 99? Chúng tôi biết rằng chúng tôi có thể gọi 50 để lắng nghe các thay đổi đối với cửa hàng, vì vậy chúng tôi có thể thử viết mã để đăng ký cửa hàng trong mọi thành phần. Nhưng, điều đó sẽ nhanh chóng trở nên rất lặp đi lặp lại và khó xử lýMay mắn thay, 14 đã tự động đăng ký vào cửa hàng Redux cho chúng tôi. Bằng cách đó, bất cứ khi nào một hành động được gửi đi, nó sẽ gọi lại hàm chọn của nó ngay lập tức. Nếu giá trị được trả về bởi bộ chọn thay đổi so với lần cuối nó chạy, thì 14 sẽ buộc thành phần của chúng ta kết xuất lại với dữ liệu mới. Tất cả những gì chúng ta phải làm là gọi 53 một lần trong thành phần của chúng ta và nó sẽ thực hiện phần còn lại cho chúng taTuy nhiên, có một điều rất quan trọng cần nhớ ở đây thận trọng 14 so sánh kết quả của nó bằng cách sử dụng so sánh tham chiếu nghiêm ngặt của 55, do đó, thành phần sẽ kết xuất lại bất kỳ lúc nào kết quả của bộ chọn là một tham chiếu mới. Điều này có nghĩa là nếu bạn tạo một tham chiếu mới trong bộ chọn của mình và trả về nó, thành phần của bạn có thể hiển thị lại mỗi khi một hành động được gửi đi, ngay cả khi dữ liệu thực sự không khácVí dụ: chuyển bộ chọn này cho 14 sẽ khiến thành phần luôn kết xuất lại, vì 57 luôn trả về một tham chiếu mảng mới 0tiền boaChúng ta sẽ nói về một cách để khắc phục vấn đề này sau trong phần này. Chúng ta cũng sẽ nói về cách bạn có thể cải thiện hiệu suất và tránh kết xuất lại không cần thiết bằng cách sử dụng chức năng bộ chọn "ghi nhớ" trong Phần 7. Các mẫu Redux tiêu chuẩn Cũng cần lưu ý rằng chúng ta không phải viết hàm chọn dưới dạng một biến riêng biệt. Bạn có thể viết một hàm chọn trực tiếp bên trong lệnh gọi tới 14, như thế này 2Gửi hành động với npm install react-redux59Bây giờ chúng tôi biết cách đọc dữ liệu từ cửa hàng Redux vào các thành phần của chúng tôi. Tuy nhiên, làm thế nào chúng ta có thể gửi các hành động đến cửa hàng từ một thành phần? . Vì chúng tôi không có quyền truy cập vào cửa hàng trong tệp thành phần, nên chúng tôi cần một số cách để có quyền truy cập vào hàm 01 bên trong các thành phần của chúng tôiKết quả là React-Redux cung cấp cho chúng ta phương thức 01 của cửa hàng. (Trên thực tế, việc triển khai hook thực sự là 04. )Vì vậy, chúng ta có thể gọi 05 trong bất kỳ thành phần nào cần gửi hành động và sau đó gọi 06 khi cầnHãy thử điều đó trong thành phần 6 của chúng tôi. Chúng tôi biết rằng chúng tôi cần cho phép người dùng nhập một số văn bản cho một mục việc cần làm mới, sau đó gửi một hành động 99 có chứa văn bản đóChúng ta sẽ viết một thành phần biểu mẫu React điển hình sử dụng để cho phép người dùng nhập văn bản biểu mẫu. Sau đó, khi người dùng nhấn phím Enter một cách cụ thể, chúng tôi sẽ gửi hành động đó src/tính năng/tiêu đề/Tiêu đề. js 2Đi qua cửa hàng với npm install react-redux09Các thành phần của chúng tôi hiện có thể đọc trạng thái từ cửa hàng và gửi hành động đến cửa hàng. Tuy nhiên, chúng ta vẫn còn thiếu một cái gì đó. Các hook React-Redux tìm đúng cửa hàng Redux ở đâu và như thế nào? Thay vào đó, chúng ta phải nói cụ thể cho React-Redux biết cửa hàng nào chúng ta muốn sử dụng trong các thành phần của mình. Chúng tôi làm điều này bằng cách hiển thị một thành phần 21 xung quanh toàn bộ 5 của chúng tôi và chuyển cửa hàng Redux làm chỗ dựa cho 21. Sau khi chúng tôi thực hiện việc này một lần, mọi thành phần trong ứng dụng sẽ có thể truy cập cửa hàng Redux nếu cầnHãy thêm nó vào tệp 24 chính của chúng tôisrc/chỉ mục. js 9Điều đó bao gồm các phần chính của việc sử dụng React-Redux với React
Bây giờ chúng ta có thể thực sự tương tác với ứng dụng. Đây là giao diện người dùng hoạt động cho đến nay Bây giờ, hãy xem xét một vài cách khác mà chúng ta có thể sử dụng chúng cùng nhau trong ứng dụng việc cần làm của mình Các mẫu React-ReduxGlobal State, Component State, và FormsBây giờ bạn có thể tự hỏi, "Tôi có luôn phải đặt tất cả trạng thái ứng dụng của mình vào cửa hàng Redux không?" Câu trả lời là không. Trạng thái toàn cầu cần thiết trên ứng dụng sẽ có trong cửa hàng Redux. Trạng thái chỉ cần thiết ở một nơi nên được giữ ở trạng thái thành phần Một ví dụ điển hình về điều này là thành phần 6 mà chúng ta đã viết trước đó. Chúng tôi có thể giữ chuỗi văn bản nhập hiện tại trong cửa hàng Redux, bằng cách gửi một hành động trong trình xử lý 20 của đầu vào và giữ nó trong bộ giảm tốc của chúng tôi. Nhưng, điều đó không mang lại cho chúng ta bất kỳ lợi ích nào. Nơi duy nhất mà chuỗi văn bản được sử dụng là ở đây, trong thành phần 6Vì vậy, thật hợp lý khi giữ giá trị đó trong móc nối 17 ở đây trong thành phần 6Tương tự như vậy, nếu chúng ta có một cờ boolean có tên là 24, thì không có thành phần nào khác trong ứng dụng quan tâm đến điều đó - nó thực sự nên giữ cục bộ cho thành phần nàytiền boaTrong ứng dụng React + Redux, trạng thái chung của bạn sẽ nằm trong cửa hàng Redux và trạng thái cục bộ của bạn sẽ ở trong các thành phần React Nếu bạn không chắc nên đặt thứ gì đó ở đâu, đây là một số quy tắc chung để xác định loại dữ liệu nào sẽ được đưa vào Redux
Đây cũng là một ví dụ điển hình về cách suy nghĩ về các biểu mẫu trong Redux nói chung. Hầu hết trạng thái biểu mẫu có lẽ không nên được giữ trong Redux. Thay vào đó, hãy giữ dữ liệu trong các thành phần biểu mẫu của bạn khi bạn đang chỉnh sửa dữ liệu đó, sau đó gửi các hành động Redux để cập nhật cửa hàng khi người dùng hoàn tất Sử dụng nhiều bộ chọn trong một thành phầnHiện tại chỉ có thành phần 7 của chúng tôi đang đọc dữ liệu từ cửa hàng. Hãy xem nó trông như thế nào khi thành phần 9 cũng bắt đầu đọc một số dữ liệu 9 cần biết ba thông tin khác nhau
Làm thế nào chúng ta có thể đọc các giá trị này vào thành phần? Chúng ta có thể gọi 14 nhiều lần trong một thành phần. Trên thực tế, đây thực sự là một ý tưởng hay - mỗi lệnh gọi tới 14 phải luôn trả về lượng trạng thái nhỏ nhất có thểChúng ta đã thấy cách viết bộ chọn đếm các việc cần làm đã hoàn thành trước đó. Đối với các giá trị bộ lọc, cả giá trị bộ lọc trạng thái và giá trị bộ lọc màu đều nằm trong lát cắt 90. Vì thành phần này cần cả hai nên chúng ta có thể chọn toàn bộ đối tượng 90Như chúng tôi đã đề cập trước đó, chúng tôi có thể đưa tất cả việc xử lý đầu vào trực tiếp vào 9 hoặc chúng tôi có thể chia nó thành các thành phần riêng biệt như 12. Để phần giải thích này ngắn gọn hơn, chúng ta sẽ bỏ qua các chi tiết chính xác về cách viết xử lý đầu vào và giả sử chúng ta có các thành phần riêng biệt nhỏ hơn được cung cấp một số dữ liệu và thay đổi các lệnh gọi lại của trình xử lý làm đạo cụVới giả định đó, các phần React-Redux của thành phần có thể trông như thế này src/features/footer/Footer. js 9Chọn dữ liệu trong các mục danh sách theo IDHiện tại, 7 của chúng tôi đang đọc toàn bộ mảng 90 và chuyển các đối tượng việc cần làm thực tế làm chỗ dựa cho từng thành phần 8Điều này hoạt động, nhưng có một vấn đề hiệu suất tiềm năng
Kết xuất lại các thành phần không tệ - đó là cách React biết liệu nó có cần cập nhật DOM hay không. Tuy nhiên, việc kết xuất lại nhiều thành phần khi không có gì thực sự thay đổi có thể trở nên quá chậm nếu danh sách quá lớn Có một vài cách chúng ta có thể cố gắng khắc phục điều này. Một tùy chọn là để họ chỉ kết xuất lại khi đạo cụ của họ thực sự thay đổi. Đây thường là một lựa chọn tốt để cải thiện hiệu suất, nhưng nó yêu cầu thành phần con luôn nhận được cùng một đạo cụ cho đến khi có gì đó thực sự thay đổi. Vì mỗi thành phần 8 đang nhận một mục việc cần làm làm chỗ dựa, nên chỉ một trong số chúng thực sự nhận được chỗ dựa đã thay đổi và phải kết xuất lạiMột tùy chọn khác là để thành phần 7 chỉ đọc một mảng ID việc cần làm từ cửa hàng và chuyển các ID đó dưới dạng đạo cụ cho thành phần 8 con. Sau đó, mỗi 8 có thể sử dụng ID đó để tìm đúng đối tượng việc cần làm mà nó cầnHãy thử xem src/features/todos/TodoList. js 0Lần này, chúng tôi chỉ chọn một mảng ID việc cần làm từ cửa hàng trong 7 và chúng tôi chuyển từng 98 làm chỗ dựa cho 99 cho các 8 conSau đó, trong 8, chúng tôi có thể sử dụng giá trị ID đó để đọc mục việc cần làm của mình. Chúng tôi cũng có thể cập nhật 8 để gửi hành động "đã bật" dựa trên ID của việc cần làmsrc/features/todos/TodoListItem. js 1Có một vấn đề với điều này, mặc dù. Chúng tôi đã nói trước đó rằng việc trả về các tham chiếu mảng mới trong bộ chọn khiến các thành phần kết xuất lại mỗi lần và hiện tại chúng tôi đang trả về một mảng ID mới trong 7. Trong trường hợp này, nội dung của mảng ID phải giống nhau nếu chúng ta chuyển đổi một việc cần làm, bởi vì chúng ta vẫn đang hiển thị các mục việc cần làm giống nhau - chúng ta chưa thêm hoặc xóa bất kỳ. Tuy nhiên, mảng chứa các ID đó là một tham chiếu mới, vì vậy, 7 sẽ hiển thị lại khi thực sự không cần thiếtMột giải pháp khả thi cho vấn đề này là thay đổi cách 14 so sánh các giá trị của nó để xem liệu chúng có thay đổi hay không. 14 có thể lấy hàm so sánh làm đối số thứ hai của nó. Hàm so sánh được gọi với các giá trị cũ và mới và trả về 07 nếu chúng được coi là giống nhau. Nếu chúng giống nhau, 14 sẽ không kết xuất lại thành phầnReact-Redux có chức năng so sánh 09 mà chúng ta có thể sử dụng để kiểm tra xem các mục bên trong mảng có còn giống nhau không. Hãy thử điều đósrc/features/todos/TodoList. js 2Bây giờ, nếu chúng ta chuyển đổi một mục việc cần làm, danh sách ID sẽ được coi là giống nhau và 7 sẽ không phải hiển thị lại. Một 8 sẽ nhận được một đối tượng việc cần làm được cập nhật và kết xuất lại, nhưng tất cả những người còn lại sẽ vẫn có đối tượng việc cần làm hiện có và hoàn toàn không phải kết xuất lạiNhư đã đề cập trước đó, bạn cũng có thể sử dụng một loại chức năng bộ chọn chuyên biệt được gọi là "bộ chọn được ghi nhớ" để giúp cải thiện kết xuất thành phần và chúng ta sẽ xem xét cách sử dụng chúng trong phần khác Những gì bạn đã họcBây giờ chúng tôi có một ứng dụng việc cần làm đang hoạt động. Ứng dụng của chúng tôi tạo một cửa hàng, chuyển cửa hàng tới lớp React UI bằng cách sử dụng 21, sau đó gọi 14 và 59 để nói chuyện với cửa hàng trong các thành phần React của chúng tôithông tinHãy tự mình triển khai phần còn lại của các tính năng giao diện người dùng còn thiếu. Đây là danh sách những thứ bạn cần thêm
Chúng tôi sẽ đề cập đến việc triển khai các bộ lọc trong Phần 7. Các mẫu Redux tiêu chuẩn Hãy xem giao diện của ứng dụng bây giờ, bao gồm các thành phần và phần mà chúng tôi đã bỏ qua để giữ cho ứng dụng này ngắn hơn Bản tóm tắt
Cái gì tiếp theo?Bây giờ giao diện người dùng của chúng ta đang hoạt động, đã đến lúc xem cách làm cho ứng dụng Redux giao tiếp với máy chủ. Trong Phần 6. Logic không đồng bộ, chúng ta sẽ nói về cách logic không đồng bộ như thời gian chờ và lệnh gọi AJAX phù hợp với luồng dữ liệu Redux |