TL; DR
Không có combineReducers()hoặc mã thủ công tương tự, initialStateluô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 initialStatesẽ 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, initialStatechiế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 createStorelà undefined. Đây là statelầ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ộ countergiảm tốc của bạn được gọi là statebằng undefined. Đây chính xác là trường hợp "kích hoạt" đối số mặc định. Do đó, statebây giờ 0là theo stategiá 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 42là đố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, statekhô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 statelà 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 createStoremà không có initialState, nó sẽ khởi tạo stateđến {}. Do đó, state.avà state.bsẽ undefinedtheo thời gian nó gọi avà bgiảm. Cả hai avà các bộ bgiảm sẽ nhận undefinedlàm đối số của chúng state và nếu chúng chỉ định statecá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 initialStatelà đố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ộ agiảm tốc với 'wat'đối số mặc định được chỉ định mà bộ bgiả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ó atrường bằng 'horse', nhưng không có btrường. Đây là lý do tại sao bộ agiảm thiểu nhận được 'horse'là của nó statevà vui mừng trả lại nó, nhưng bộ bgiảm thiểu nhận được undefinednhư của nó statevà 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 undefinedlà 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.