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
มันจะเริ่มต้นstate
to {}
. ดังนั้นstate.a
และstate.b
จะเป็นไปundefined
ตามเวลาที่เรียกa
และb
ตัวลด ทั้งสองa
และb
reducers จะได้รับ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
ลดจะเข้าใจซึ่งชิ้นส่วนของสถานะเริ่มต้นเป็นของมันอยู่บนพื้นฐานที่สำคัญที่ใช้ในการ ขอบคุณอีกครั้งมาก ๆ