Không phải Redux chỉ là nhà nước toàn cầu được tôn vinh?


84

Vì vậy, tôi đã bắt đầu học React cách đây một tuần và chắc chắn tôi đã gặp phải vấn đề về trạng thái và cách các thành phần phải giao tiếp với phần còn lại của ứng dụng. Tôi đã tìm kiếm xung quanh và Redux dường như là hương vị của tháng. Tôi đã đọc qua tất cả các tài liệu và tôi nghĩ đó thực sự là một ý tưởng mang tính cách mạng. Đây là suy nghĩ của tôi về nó:

State thường được đồng ý là khá xấu và là một nguồn lỗi lớn trong lập trình. Thay vì phân tán tất cả trong ứng dụng của bạn, Redux nói tại sao không chỉ tập trung tất cả trong một cây trạng thái toàn cục mà bạn phải thực hiện các hành động để thay đổi? Nghe có vẻ thú vị. Tất cả các chương trình đều cần trạng thái, vì vậy hãy gắn nó vào một không gian không tinh khiết và chỉ sửa đổi nó từ bên trong đó để các lỗi dễ theo dõi. Sau đó, chúng tôi cũng có thể khai báo liên kết các phần trạng thái riêng lẻ với các thành phần React và để chúng tự động vẽ lại và mọi thứ đều đẹp.

Tuy nhiên, tôi có hai câu hỏi về toàn bộ thiết kế này. Đối với một, tại sao cây trạng thái cần phải là bất biến? Giả sử tôi không quan tâm đến gỡ lỗi du hành thời gian, tải lại nóng và đã triển khai hoàn tác / làm lại trong ứng dụng của mình. Nó chỉ có vẻ rất cồng kềnh để phải làm điều này:

case COMPLETE_TODO:
  return [
    ...state.slice(0, action.index),
    Object.assign({}, state[action.index], {
      completed: true
    }),
    ...state.slice(action.index + 1)
  ];

Thay vì điều này:

case COMPLETE_TODO:
  state[action.index].completed = true;

Chưa kể tôi đang làm một bảng trắng trực tuyến chỉ để tìm hiểu và mọi thay đổi trạng thái có thể đơn giản như thêm một nét vẽ vào danh sách lệnh. Sau một thời gian (hàng trăm nét vẽ), việc sao chép toàn bộ mảng này có thể bắt đầu trở nên cực kỳ tốn kém và tốn thời gian.

Tôi ổn với cây trạng thái toàn cục độc lập với giao diện người dùng được thay đổi thông qua các hành động, nhưng nó có thực sự cần phải bất biến không? Có gì sai với một triển khai đơn giản như thế này (bản nháp rất thô. Được viết trong 1 phút)?

var store = { items: [] };

export function getState() {
  return store;
}

export function addTodo(text) {
  store.items.push({ "text": text, "completed", false});
}

export function completeTodo(index) {
  store.items[index].completed = true;
}

Nó vẫn là một cây trạng thái toàn cục được biến đổi thông qua các hành động được phát ra nhưng cực kỳ đơn giản và hiệu quả.


2
"Đối với một, tại sao cây trạng thái cần phải bất biến?" --- thì bạn phải cung cấp một thuật toán để xác định xem dữ liệu có thay đổi hay không. Không thể triển khai nó cho một cấu trúc dữ liệu tùy ý (nếu nó có thể thay đổi). Lấy immutablejsvà sử dụng return state.setIn([action.index, 'completed'], true);để giảm bớt các tấm lò hơi.
zerkms

1
Tái return state.map(i => i.index == action.index ? {...i, completed: true} : i);
bút

Câu trả lời:


52

Không phải Redux chỉ là nhà nước toàn cầu được tôn vinh?

Tất nhiên là thế rồi. Nhưng điều tương tự đối với mọi cơ sở dữ liệu bạn đã từng sử dụng. Tốt hơn nên coi Redux như một cơ sở dữ liệu trong bộ nhớ - cơ sở dữ liệu mà các thành phần của bạn có thể phụ thuộc vào.

Tính bất biến cho phép kiểm tra xem có bất kỳ cây con nào đã bị thay đổi rất hiệu quả vì nó đơn giản hóa việc kiểm tra danh tính.

Có, việc triển khai của bạn hiệu quả, nhưng toàn bộ dom ảo sẽ phải được kết xuất lại mỗi khi cây được thao tác bằng cách nào đó.

Nếu bạn đang sử dụng React, nó cuối cùng sẽ tạo ra sự khác biệt so với dom thực tế và thực hiện các thao tác tối ưu hóa hàng loạt tối thiểu, nhưng kết xuất toàn bộ từ trên xuống vẫn không hiệu quả.

Đối với một cây bất biến, các thành phần không trạng thái chỉ cần kiểm tra xem (các) cây con mà nó phụ thuộc vào, có khác biệt về danh tính so với (các) giá trị trước đó hay không, và nếu có - hoàn toàn có thể tránh được việc hiển thị.


3
Đây không phải là một chút tối ưu hóa quá sớm sao? Ngoài ra, làm thế nào để chúng ta biết rằng chi phí liên tục sao chép đối tượng bất biến là ít hơn tái dựng hình DOM (cũng sẽ không phản ứng DOM ảo của nhiều giảm thiểu chi phí này?)
Ryan Peschel

3
Chà, thư viện GUI tối ưu hóa kiểu này trong một thời gian dài (Tham khảo: bitquabit.com/post/the-more-things-change ) Thêm vào đó, việc quản lý cấu trúc dữ liệu bất biến không tốn kém như bạn nghĩ - ví dụ: nếu một nút được thay đổi, chỉ một chuỗi cha mẹ cần liên kết - phần còn lại của các nút vẫn không bị ảnh hưởng. Vì vậy, chúng tôi không sao chép toàn bộ cấu trúc dữ liệu cho mọi hành động - chúng tôi sử dụng lại các thành phần con chưa thay đổi để xây dựng cấu trúc dữ liệu mới.
lorefnon

4
Ngoài ra, thứ React Virtual DOM không hẳn là ma thuật đen tối - Trích dẫn từ tài liệu React: "Tạo ra số lượng phép toán tối thiểu để biến một cây này thành một cây khác là một vấn đề phức tạp và được nghiên cứu kỹ lưỡng - Các thuật toán hiện đại có độ phức tạp theo thứ tự O (n3) trong đó n là số nút trong cây ".
lorefnon

2
Lý do React có thể hoạt động tốt hơn nhiều trong thực tế là vì: React dựa vào heuristics - vì vậy: "Nếu bạn không cung cấp các khóa ổn định (bằng cách sử dụng Math.random () chẳng hạn), tất cả các cây con sẽ được hiển thị lại mọi lần. Bằng cách cho phép người dùng lựa chọn phím, họ có khả năng tự bắn vào chân mình. " Vì vậy, giống như bạn có thể trợ giúp React bằng cách cung cấp các khóa ổn định, cũng giống như cách bạn có thể giúp React bằng cách cung cấp các đạo cụ dữ liệu bất biến.
lorefnon

1
Về mảng nét vẽ của bạn - vui lòng tham khảo: facebook.github.io/immutable-js/docs/#/List Trích dẫn từ tài liệu: Danh sách được sắp xếp theo thứ tự các bộ sưu tập dày đặc được lập chỉ mục, giống như Mảng JavaScript. Danh sách triển khai Deque, với việc bổ sung và loại bỏ hiệu quả cả phần cuối (đẩy, bật) và đầu (không chuyển, dịch chuyển).
lorefnon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.