2016-02-27 15 views
16

Tôi mới sử dụng React và thậm chí mới hơn đối với Redux. Cho đến nay, đã sử dụng cả hai cùng nhau cho một ứng dụng hộp cát nhỏ, tôi thích chúng.Redux - tại sao tất cả đều ở một nơi, ngay cả trạng thái không phải là toàn cầu?

Khi nói đến một ứng dụng lớn hơn, tuy nhiên, tôi bắt đầu tự hỏi về điều này: Tại sao Redux giữ toàn bộ trạng thái đơn đăng ký của bạn trong một cửa hàng?

Nếu tôi có một ứng dụng có nhiều phần khác nhau (và mỗi phần đó đều có các thành phần của chúng), sẽ có ý nghĩa với tôi để giữ trạng thái của từng phần đó (trong thành phần cấp cao nhất của mỗi phần) , miễn là trạng thái của chúng không ảnh hưởng đến mọi thứ với các thành phần khác.

Tôi không chắc chắn về lợi ích của việc có trạng thái cho tất cả mọi thứ ở một nơi, khi các phần của trạng thái đó không liên quan gì đến các phần khác của nó. Nếu thành phần A không bị ảnh hưởng bởi trạng thái của thành phần B, và ngược lại, trạng thái của chúng không được giữ trong các thành phần của chúng thay vì ở gốc?

Tôi không thể có trạng thái ảnh hưởng toàn cầu ở gốc và trạng thái cụ thể cho từng thành phần trong các thành phần của riêng chúng? Tôi lo ngại về việc ném tất cả trạng thái thành phần cụ thể, tất cả các đường lên chuỗi đối tượng trạng thái toàn cầu (đặc biệt là khi React nhấn mạnh luồng từ trên xuống).

+1

Tôi nghĩ có [thảo luận có liên quan về vấn đề này trên Github của họ] (https://github.com/reactjs/redux/issues/1385)? Đã không được chính thức trả lời nhưng nó đang được thảo luận - không chắc chắn nếu điều đó thực sự giúp mặc dù. – aug

+0

điều gì sẽ xảy ra nếu bạn thiết kế lại ứng dụng của mình và trạng thái không toàn cầu phải toàn cầu bây giờ? – Theo

+0

@aug: Cảm ơn bạn đã đăng bài. Một sự giàu có của thông tin đó. Nó giúp trả lời câu hỏi tôi có về "Tôi có thể sử dụng các cửa hàng redux và phản ứng nhà nước?" – Skitterm

Trả lời

8

Lợi thế chính của trạng thái toàn cục cho ứng dụng giao diện người dùng là bạn có thể theo dõi các thay đổi trạng thái của toàn bộ ứng dụng BẤT CỨ NÀO.

tldr; bạn luôn có thể lưu và dự đoán trạng thái của ứng dụng dễ dàng vì có một nguồn chân lý duy nhất.

Sự cố với các thành phần tự quản lý là chúng tạo ra sự kết hợp không thể đoán trước của các trạng thái có thể xảy ra. Bạn không thể dễ dàng biết trạng thái ứng dụng của bạn sẽ ở trong đó nếu XComponent thay đổi chính nó bởi vì bạn sẽ phải sắp xếp lại YComponent và ZComponent và sau đó cho họ biết về trạng thái của nhau để họ đưa ra quyết định dựa trên đó và xác định trạng thái ứng dụng tổng thể.

Điều này thực sự thích hợp với ngữ cảnh. Nếu tôi có quyết định dựa trên việc biết trạng thái của 3 phần riêng biệt của trạng thái ứng dụng không có mối quan hệ trực tiếp về thành phần giao diện người dùng của họ, làm cách nào để có được bối cảnh đưa ra quyết định đó và truyền đạt kết quả đó cho toàn bộ ứng dụng ? Không có quyền truy cập vào một biểu diễn trạng thái đầy đủ, không có cách nào dễ dàng để có được sự tổng hợp ngữ cảnh đó.

Redux (và các mẫu khác như tỷ lệ trong thuốc thử) giải quyết vấn đề này với trạng thái thống nhất toàn cầu. Hành động của bạn chỉ là sứ giả với những thay đổi trạng thái nhưng Cửa hàng của bạn là người giữ ngữ cảnh. Nếu không có một cửa hàng duy nhất, các thành phần của bạn sẽ giống như các lãnh chúa phong kiến ​​cãi nhau về trạng thái của những thái độ điên cuồng liên quan của họ. Các cửa hàng là kết quả của một đầu sỏ chặt chẽ đan (combineReducers()) mà quy tắc nhà nước ứng dụng của bạn với một nắm tay sắt và giữ lỗi đi :)

Trạng thái toàn cầu hoạt động tốt cho giao diện người dùng và giải quyết rất nhiều vấn đề, ngay cả khi nó phản thực hành trực quan hoặc thậm chí không tốt cho các loại phần mềm khác. Điều đó nói rằng, nó được ghi nhận thường xuyên rằng không phải tất cả các trạng thái ứng dụng của bạn cần phải ở trong kho lưu trữ Redux. Ngoài ra, bạn có thể xóa dữ liệu không còn hữu ích/có liên quan nữa. Cuối cùng, Nhà nước chỉ có liên quan đến một thành phần nhất định (và hành vi/hiển thị của nó) không cần phải được phản ánh trong cửa hàng toàn cầu (nhất thiết).

Sự tách rời liên quan đến trừu tượng trong Redux là trình giảm tốc vì bạn có thể tạo nhiều bộ giảm tốc và kết hợp chúng để tạo chuỗi logic cho bản cập nhật cửa hàng.

Với bộ giảm tốc, bạn vẫn đang "tách" logic trạng thái của bạn bằng mã, nhưng trên thực tế, tất cả được coi là một cây duy nhất khi chạy. Điều này giúp trạng thái của bạn thay đổi có thể dự đoán và nguyên tử, nhưng cho phép tổ chức tốt, đóng gói và tách mối quan tâm.

+0

Cảm ơn. Điều đó làm cho rất nhiều ý nghĩa. Dường như có một nhược điểm trong việc làm cho các thành phần "React with redux" có thể tái sử dụng được. Tôi đồng ý với bạn về trạng thái tập trung, nhưng tôi thấy rằng nếu bạn muốn sử dụng thành phần trong một ứng dụng khác, bạn cần phải thực hiện nhiều kết nối với nhau (bộ giảm tốc, cấu trúc trạng thái cần phải giống nhau khi bạn ánh xạ trạng thái đạo cụ của bạn), trong khi nếu nhà nước được xử lý cục bộ trong thành phần, bạn có thể giảm nhiều thành phần trong một ứng dụng React khác và bắt đầu. – Skitterm

+1

Vâng, hãy suy nghĩ về điều đó trong một giây: Nếu trạng thái được quản lý trong thành phần, thì khi bạn thả nó vào một ứng dụng khác, ứng dụng đó tùy chỉnh hành vi và tương tác của thành phần đó như thế nào? Câu trả lời là nó KHÔNG THỂ mà không sửa đổi thành phần. Nếu thành phần là trạng thái không trạng thái (câm cơ bản) và chỉ phát ra các sự kiện (hành động) và nhận đạo cụ, bạn có thể đặt nó vào ứng dụng _any_ và ứng dụng có thể dựa vào nó để theo dõi một cách mù quáng mà không diễn giải chúng vì một số quy tắc còn sót lại của nó ứng dụng trước. Có lý? –

10

Tại sao chúng ta di chuyển trạng thái liên tục của chúng ta vào cơ sở dữ liệu, thay vì cho phép mỗi thành phần phụ trợ quản lý trạng thái của chúng trong các tệp riêng biệt?

Vì việc truy vấn, gỡ lỗi và tuần tự hóa trạng thái ứng dụng tổng thể của chúng tôi trở nên dễ dàng hơn nhiều.

Redux được lấy cảm hứng từ một ngôn ngữ được gọi là Elm, cũng thúc đẩy việc sử dụng một mô hình duy nhất. Tác giả của Elm có một lý do chính đáng hơn về lý do tại sao đó là một chất lượng quan trọng cho các ứng dụng.

Có một nguồn chân lý duy nhất. Cách tiếp cận truyền thống buộc bạn phải viết một số lượng phong nha của mã tùy chỉnh và dễ bị lỗi để đồng bộ hóa trạng thái giữa nhiều thành phần trạng thái khác nhau. (Trạng thái của tiện ích này cần được đồng bộ hóa với trạng thái ứng dụng, cần được đồng bộ hóa với một số tiện ích khác, v.v.) Bằng cách đặt tất cả trạng thái của bạn ở một vị trí, bạn sẽ loại bỏ toàn bộ lớp lỗi trong đó hai thành phần nhận được vào trạng thái không nhất quán. Chúng tôi cũng nghĩ rằng bạn sẽ kết thúc viết ít mã hơn nhiều. Đó là quan sát của chúng tôi ở Elm cho đến nay.

Tôi thấy khái niệm này dễ học và dễ hiểu hơn trong khi giải quyết nó từ số Re-frame của ClojureScript và xem số videos on Om Next của David Nolen. Re-frame README cho dự án cũng là một tài nguyên học tập tuyệt vời.

Dưới đây là một số lý do cá nhân của tôi về lý do tại sao nhà nước toàn cầu là giải pháp thanh lịch hơn.

Linh kiện đơn giản

Một kịch bản phổ biến phát sinh trong nhiều ứng dụng dựa trên thành phần trạng thái, cần phải sửa đổi trạng thái sống trong thành phần khác. Ví dụ: nhấp vào nút chỉnh sửa trong thành phần NameTag sẽ mở trình chỉnh sửa cho phép người dùng sửa đổi một số dữ liệu sống ở trạng thái của thành phần Profile (phụ huynh của NameTag). Cách để giải quyết vấn đề này là truyền các callback xử lý, sau đó truyền dữ liệu sao lưu cây thành phần. Mẫu này dẫn đến các luồng dữ liệu phụ khó hiểu trong luồng dữ liệu một chiều hiện có của các ứng dụng React.

Với trạng thái toàn cục, các thành phần chỉ gửi các hành động kích hoạt cập nhật cho trạng thái đó. Cả hai thành phần và hành động có thể được tham số hóa để gửi thông tin theo ngữ cảnh cho người dùng (ví dụ: id của người dùng có tên tôi đang chỉnh sửa) là gì. Bạn không cần phải suy nghĩ nhiều về cách bạn sẽ giao tiếp những thay đổi cho tiểu bang, bởi vì bạn biết chính xác vị trí của tiểu bang, và hành động là cơ chế được xác định trước để gửi những thay đổi đó ở đó.

Chức năng tinh khiết

Khi trạng thái ứng dụng của bạn sống ở một địa điểm duy nhất, các thành phần mà làm cho nó có thể là chức năng thuần túy mà phải mất trạng thái như một cuộc tranh cãi. Họ chỉ xem xét dữ liệu và trả lại chế độ xem có thể gửi các hành động để thực hiện cập nhật.

Các chức năng này có tính minh bạch tham chiếu, có nghĩa là đối với bất kỳ bộ đầu vào nào đã cho, luôn có cùng một đầu ra chính xác. Điều này là lý tưởng để thử nghiệm và bạn kết thúc với các thành phần đơn giản để kiểm tra.

serialization

Trong một truyền thống Phản ứng ứng dụng với các thành phần trạng thái, serializing toàn bộ trạng thái ứng dụng sẽ là một cơn ác mộng. Nó sẽ liên quan đến việc vượt qua toàn bộ cây thành phần và trích xuất giá trị trạng thái từ mỗi thành phần, trước khi thu thập tất cả chúng trong một cấu trúc dữ liệu và mã hóa nó.

Việc tăng cường lại các thành phần với trạng thái tuần tự sẽ có nghĩa là quy trình tương tự, ngoại trừ bạn cũng phải tìm ra loại thành phần nào chịu trách nhiệm về dữ liệu nào, để bạn có thể tái tạo chính xác cây thành phần. Điều này cũng có nghĩa là lưu trữ thông tin bổ sung về các loại thành phần trong tiểu bang của bạn.

Với trạng thái toàn cầu, bạn chỉ cần mã hóa và giải mã chính xác vị trí của nó.

Undo/Redo

Để thực hiện undo/redo với tình trạng toàn cầu, bạn cần lưu trữ quốc gia trong danh sách, chứ không phải là thay thế cuối cùng một khi nó cập nhật. Một con trỏ chỉ mục có thể kiểm soát trạng thái hiện tại của bạn.

Với các thành phần trạng thái, điều này sẽ yêu cầu mỗi thành phần thực hiện cơ chế này. Không chỉ có rất nhiều công việc phụ, nhưng nó cũng tạo ra một điểm khác trong ứng dụng của bạn cho các lỗi được giới thiệu. Mã tốt nhất là không có mã, như họ nói.

Action Playback

Trong Redux (và mô hình Flux nói chung) chúng ta có thể theo dõi các hành động đã được chơi, sau đó chơi chúng trở lại trong bối cảnh khác để sản xuất một cách chính xác tình trạng tương tự.

Nếu bạn giới thiệu thành phần địa phương nhà nước, sau đó bạn có thể nói lời tạm biệt với điều này. Các bản cập nhật cho trạng thái cục bộ có thể đến từ các trình xử lý sự kiện DOM, các yêu cầu mạng, các hoạt động không đồng bộ (và nhiều hơn nữa). Các hoạt động này không thể được tuần tự hóa, có nghĩa là chúng không thể phát lại được.

+8

Tôi muốn lưu ý rằng ** chúng tôi không đề nghị bạn nên đi tất cả trong việc giữ tất cả các trạng thái trong Redux. Khi nó dẫn đến mã phức tạp, đừng làm điều đó. ** Ví dụ, tôi sẽ không đặt những thứ như "được thả xuống" trong Redux vì nó hoàn toàn không liên quan đến bất kỳ thành phần nào khác. –

Các vấn đề liên quan