TL; ดร
หากไม่มีcombineReducers()รหัสด้วยตนเองหรือคล้ายกันinitialStateจะชนะstate = ...ในตัวลดเสมอเนื่องจากการstateส่งผ่านไปยังตัวลดคือ initialStateและไม่ใช่ undefinedดังนั้นไวยากรณ์ของอาร์กิวเมนต์ ES6 จึงไม่ถูกนำไปใช้ในกรณีนี้
ด้วยcombineReducers()พฤติกรรมที่เหมาะสมยิ่งขึ้น ตัวลดที่ระบุสถานะinitialStateจะได้รับสิ่งstateนั้น ตัวลดอื่น ๆ จะได้รับundefined และด้วยเหตุนี้จะถอยกลับไปที่state = ...อาร์กิวเมนต์เริ่มต้นที่ระบุ
โดยทั่วไปการinitialStateชนะในสถานะที่ตัวลดระบุ สิ่งนี้ช่วยให้ตัวลดขนาดระบุข้อมูลเริ่มต้นที่เหมาะสมกับพวกเขาเป็นอาร์กิวเมนต์เริ่มต้น แต่ยังอนุญาตให้โหลดข้อมูลที่มีอยู่ (ทั้งหมดหรือบางส่วน) เมื่อคุณให้ความชุ่มชื้นแก่ที่จัดเก็บจากหน่วยเก็บข้อมูลถาวรหรือเซิร์ฟเวอร์
ก่อนอื่นให้พิจารณากรณีที่คุณมีตัวลดเพียงตัวเดียว สมมติว่าคุณไม่ได้ใช้
combineReducers()
จากนั้นตัวลดของคุณอาจมีลักษณะดังนี้:
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT': return state + 1;
case 'DECREMENT': return state - 1;
default: return state;
}
}
สมมติว่าคุณสร้างร้านค้าด้วยมัน
import { createStore } from 'redux';
let store = createStore(counter);
console.log(store.getState());
สถานะเริ่มต้นเป็นศูนย์ ทำไม? เพราะอาร์กิวเมนต์ที่สองจะเป็นcreateStore undefinedนี่คือการstateส่งผ่านไปยังตัวลดของคุณในครั้งแรก เมื่อ Redux เริ่มต้นระบบจะส่งการดำเนินการ "จำลอง" เพื่อเติมเต็มสถานะ ดังนั้นตัวcounterลดของคุณจึงถูกเรียกว่าstateเท่ากับundefined. นี่คือกรณีที่ "เปิดใช้งาน" อาร์กิวเมนต์เริ่มต้น ดังนั้นstateตอนนี้0เป็นไปตามค่าเริ่มต้นstate( state = 0) สถานะนี้ ( 0) จะถูกส่งกลับ
ลองพิจารณาสถานการณ์อื่น:
import { createStore } from 'redux';
let store = createStore(counter, 42);
console.log(store.getState());
ทำไมถึงเป็น42เช่นนี้ไม่ใช่0ครั้งนี้ เพราะcreateStoreถูกเรียกด้วย42เป็นอาร์กิวเมนต์ที่สอง อาร์กิวเมนต์นี้จะstateส่งผ่านไปยังตัวลดของคุณพร้อมกับการดำเนินการจำลอง คราวstateนี้ไม่ได้กำหนด (มัน42!) ดังนั้นไวยากรณ์อาร์กิวเมนต์เริ่มต้น ES6 จึงไม่มีผล stateเป็น42และ42ถูกส่งกลับจากลด
combineReducers()ตอนนี้ขอพิจารณากรณีที่คุณใช้
คุณมีตัวลดสองตัว:
function a(state = 'lol', action) {
return state;
}
function b(state = 'wat', action) {
return state;
}
ตัวลดที่สร้างขึ้นโดยcombineReducers({ a, b })มีลักษณะดังนี้:
function combined(state = {}, action) {
return {
a: a(state.a, action),
b: b(state.b, action)
};
}
ถ้าเราเรียกcreateStoreโดยไม่มีinitialStateมันจะเริ่มต้นstateto {}. ดังนั้นstate.aและstate.bจะเป็นไปundefinedตามเวลาที่เรียกaและbตัวลด ทั้งสองaและbreducers จะได้รับundefinedเป็นของพวกเขา stateมีปากเสียงและถ้าพวกเขาระบุค่าเริ่มต้นstateค่าเหล่านั้นจะถูกส่งกลับ นี่คือวิธีที่ตัวลดรวมส่งคืน{ a: 'lol', b: 'wat' }อ็อบเจ็กต์สถานะในการเรียกใช้ครั้งแรก
import { createStore } from 'redux';
let store = createStore(combined);
console.log(store.getState());
ลองพิจารณาสถานการณ์อื่น:
import { createStore } from 'redux';
let store = createStore(combined, { a: 'horse' });
console.log(store.getState());
ตอนนี้ผมระบุเป็นอาร์กิวเมนต์ไปinitialState createStore()สถานะที่ส่งคืนจากตัวลดแบบรวมจะรวมสถานะเริ่มต้นที่ฉันระบุสำหรับตัวaลดกับ'wat'อาร์กิวเมนต์เริ่มต้นที่ระบุว่าตัวbลดเลือกเอง
ลองนึกถึงสิ่งที่ตัวลดรวมทำ:
function combined(state = {}, action) {
return {
a: a(state.a, action),
b: b(state.b, action)
};
}
ในกรณีนี้ถูกระบุดังนั้นจึงไม่ได้ถอยกลับไปstate {}มันเป็นวัตถุที่มีaฟิลด์เท่ากับ'horse'แต่ไม่มีbฟิลด์ นี่คือสาเหตุที่ตัวaลดได้รับ'horse'เป็นของมันstateและยินดีที่จะส่งคืน แต่ตัวbลดได้รับundefinedเป็นของมันstateจึงส่งคืนแนวคิดของค่าเริ่มต้นstate(ในตัวอย่างของเรา'wat') นี่คือวิธีที่เราได้รับ{ a: 'horse', b: 'wat' }ผลตอบแทน
หากต้องการสรุปสิ่งนี้หากคุณยึดติดกับข้อตกลง Redux และคืนสถานะเริ่มต้นจากตัวลดเมื่อถูกเรียกด้วยundefinedเป็นstateอาร์กิวเมนต์ (วิธีที่ง่ายที่สุดในการนำไปใช้คือการระบุstateค่าอาร์กิวเมนต์เริ่มต้น ES6) คุณจะมี พฤติกรรมที่มีประโยชน์ที่ดีสำหรับตัวลดแบบรวม พวกเขาจะชอบค่าที่สอดคล้องกันในinitialStateวัตถุที่คุณส่งผ่านไปยังcreateStore()ฟังก์ชัน แต่ถ้าคุณไม่ผ่านใด ๆ หรือหากไม่ได้ตั้งค่าฟิลด์ที่เกี่ยวข้องstateไว้อาร์กิวเมนต์เริ่มต้นที่ระบุโดยตัวลดจะถูกเลือกแทนวิธีนี้ใช้งานได้ดีเนื่องจากให้ทั้งการเริ่มต้นและการให้ความชุ่มชื้นของข้อมูลที่มีอยู่ แต่ช่วยให้ตัวลดแต่ละตัวรีเซ็ตสถานะได้หากข้อมูลไม่ได้รับการเก็บรักษา แน่นอนว่าคุณสามารถใช้รูปแบบนี้ซ้ำได้เนื่องจากคุณสามารถใช้combineReducers()ในหลายระดับหรือแม้แต่เขียนตัวลดด้วยตนเองโดยการเรียกตัวลดขนาดและให้เป็นส่วนที่เกี่ยวข้องของแผนผังสถานะ
combineReducersลดจะเข้าใจซึ่งชิ้นส่วนของสถานะเริ่มต้นเป็นของมันอยู่บนพื้นฐานที่สำคัญที่ใช้ในการ ขอบคุณอีกครั้งมาก ๆ