TL; DR
Không có combineReducers()
hoặc mã thủ công tương tự, initialState
luôn thắng state = ...
trong bộ giảm tốc vì giá trị state
được truyền cho bộ giảm tốc là initialState
và không phải undefined
, vì vậy cú pháp đối số ES6 không được áp dụng trong trường hợp này.
Với combineReducers()
các hành vi có nhiều sắc thái hơn. Những bộ giảm có trạng thái được chỉ định initialState
sẽ nhận được điều đó state
. Các bộ giảm khác sẽ nhận được undefined
và do đó sẽ trở lại state = ...
đối số mặc định mà chúng chỉ định.
Nói chung, initialState
chiến thắng trạng thái được chỉ định bởi bộ giảm tốc. Điều này cho phép các bộ giảm chỉ định dữ liệu ban đầu có ý nghĩa đối với chúng làm đối số mặc định, nhưng cũng cho phép tải dữ liệu hiện có (toàn bộ hoặc một phần) khi bạn cung cấp dịch vụ lưu trữ từ một số lưu trữ liên tục hoặc máy chủ.
Trước tiên, hãy xem xét một trường hợp mà bạn có một bộ giảm tốc duy nhất.
Nói rằng bạn không sử dụng combineReducers()
.
Sau đó, bộ giảm tốc của bạn có thể trông như thế này:
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT': return state + 1;
case 'DECREMENT': return state - 1;
default: return state;
}
}
Bây giờ giả sử bạn tạo một cửa hàng với nó.
import { createStore } from 'redux';
let store = createStore(counter);
console.log(store.getState());
Trạng thái ban đầu bằng không. Tại sao? Bởi vì đối số thứ hai createStore
là undefined
. Đây là state
lần đầu tiên được chuyển cho bộ giảm tốc của bạn. Khi Redux khởi tạo, nó sẽ gửi một hành động "giả" để lấp đầy trạng thái. Vì vậy, bộ counter
giảm tốc của bạn được gọi là state
bằng undefined
. Đây chính xác là trường hợp "kích hoạt" đối số mặc định. Do đó, state
bây giờ 0
là theo state
giá trị mặc định ( state = 0
). Trạng thái này ( 0
) sẽ được trả về.
Hãy xem xét một kịch bản khác:
import { createStore } from 'redux';
let store = createStore(counter, 42);
console.log(store.getState());
Tại sao lại là 42
, và không phải 0
, lần này? Bởi vì createStore
được gọi 42
là đối số thứ hai. Đối số này trở thành đối số state
được chuyển đến trình giảm bớt của bạn cùng với hành động giả. Lần này, state
không phải là không xác định (đó là 42
!), Vì vậy cú pháp đối số mặc định của ES6 không có tác dụng. Các state
là 42
, và 42
được trả về từ giảm tốc.
Bây giờ chúng ta hãy xem xét một trường hợp mà bạn sử dụng combineReducers()
.
Bạn có hai bộ giảm tốc:
function a(state = 'lol', action) {
return state;
}
function b(state = 'wat', action) {
return state;
}
Bộ giảm tốc được tạo bởi combineReducers({ a, b })
trông giống như sau:
function combined(state = {}, action) {
return {
a: a(state.a, action),
b: b(state.b, action)
};
}
Nếu chúng ta gọi createStore
mà không có initialState
, nó sẽ khởi tạo state
đến {}
. Do đó, state.a
và state.b
sẽ undefined
theo thời gian nó gọi a
và b
giảm. Cả hai a
và các bộ b
giảm sẽ nhận undefined
làm đối số của chúng state
và nếu chúng chỉ định state
các giá trị mặc định , các giá trị đó sẽ được trả về. Đây là cách trình giảm thiểu kết hợp trả về một { a: 'lol', b: 'wat' }
đối tượng trạng thái trong lần gọi đầu tiên.
import { createStore } from 'redux';
let store = createStore(combined);
console.log(store.getState());
Hãy xem xét một kịch bản khác:
import { createStore } from 'redux';
let store = createStore(combined, { a: 'horse' });
console.log(store.getState());
Bây giờ tôi đã chỉ định initialState
là đối số cho createStore()
. Trạng thái được trả về từ bộ giảm tốc kết hợp kết hợp trạng thái ban đầu mà tôi đã chỉ định cho bộ a
giảm tốc với 'wat'
đối số mặc định được chỉ định mà bộ b
giảm tốc đã chọn chính nó.
Hãy nhớ lại những gì mà bộ giảm tốc kết hợp làm:
function combined(state = {}, action) {
return {
a: a(state.a, action),
b: b(state.b, action)
};
}
Trong trường hợp này, state
đã được chỉ định để nó không rơi trở lại {}
. Đó là một đối tượng có a
trường bằng 'horse'
, nhưng không có b
trường. Đây là lý do tại sao bộ a
giảm thiểu nhận được 'horse'
là của nó state
và vui mừng trả lại nó, nhưng bộ b
giảm thiểu nhận được undefined
như của nó state
và do đó trả lại ý tưởng về mặc định state
(trong ví dụ của chúng tôi, 'wat'
). Đây là cách chúng tôi nhận { a: 'horse', b: 'wat' }
lại.
Tóm lại, nếu bạn tuân theo các quy ước Redux và trả về trạng thái ban đầu từ các bộ giảm khi chúng được gọi undefined
là state
đối số (cách dễ nhất để triển khai điều này là chỉ state
định giá trị đối số mặc định của ES6), bạn sẽ có một hành vi hữu ích tốt cho các bộ giảm kết hợp. Họ sẽ thích giá trị tương ứng trong initialState
đối tượng mà bạn truyền cho createStore()
hàm, nhưng nếu bạn không chuyển bất kỳ giá trị nào hoặc nếu trường tương ứng không được đặt, thì state
đối số mặc định được chỉ định bởi trình rút gọn sẽ được chọn thay thế.Cách tiếp cận này hoạt động tốt vì nó cung cấp cả khởi tạo và hydrat hóa dữ liệu hiện có, nhưng cho phép từng bộ giảm tốc đặt lại trạng thái của chúng nếu dữ liệu của chúng không được bảo toàn. Tất nhiên, bạn có thể áp dụng mô hình này một cách đệ quy, vì bạn có thể sử dụng combineReducers()
ở nhiều cấp độ, hoặc thậm chí soạn các bộ giảm tốc theo cách thủ công bằng cách gọi các bộ giảm và cung cấp cho chúng phần có liên quan của cây trạng thái.
combineReducers
. Cảm ơn bạn một lần nữa rất nhiều.