javascript - นี่คือวิธีที่ถูกต้องในการลบไอเท็มโดยใช้ redux หรือไม่?
ฉันรู้ว่าฉันไม่ควรแก้ไขข้อมูลนำเข้าโดยตรงและควรทำการโคลนวัตถุเพื่อแก้ไข ฉันกำลังปฏิบัติตามแนวทางที่ใช้ในโปรเจกต์เริ่มต้นของ Redux ที่ใช้:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
สำหรับการเพิ่มรายการ - ฉันเข้าใจการใช้ spread เพื่อเพิ่มรายการในอาร์เรย์แล้ว
สำหรับการลบ ฉันใช้:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
แต่นี่กำลังเปลี่ยนแปลงวัตถุ state ของอินพุต - สิ่งนี้ห้ามหรือเปล่าแม้ว่าฉันจะส่งคืนวัตถุใหม่?
คำตอบ #1
ไม่เคย เปลี่ยนแปลงสถานะของคุณ
แม้ว่าคุณจะกำลังส่งกลับอ็อบเจ็กต์ใหม่ คุณก็ยังคงปนเปื้อนอ็อบเจ็กต์เก่า ซึ่งคุณไม่ต้องการทำเลย นี่ทำให้เกิดปัญหาเมื่อทำการเปรียบเทียบระหว่างสถานะเก่าและสถานะใหม่ ตัวอย่างเช่น ใน shouldComponentUpdate ที่ react-redux ใช้ภายใต้ระบบเบื้องหลัง นอกจากนี้ยังทำให้การเดินทางข้ามเวลาที่ผ่านมาเป็นไปไม่ได้ (เช่น การเลิกทำและทำซ้ำ)
แทนที่จะใช้เช่นนั้น ให้ใช้วิธีการที่ไม่เปลี่ยนแปลงเสมอ ใช้ Array#slice เสมอและอย่าใช้ Array#splice
จากโค้ดของคุณ ฉันสันนิษฐานว่า action.payload คือดัชนีของรายการที่กำลังถูกลบ วิธีที่ดีกว่าคือดังนี้:
items: [
...state.items.slice(0, action.payload),
...state.items.slice(action.payload + 1)
],
คำตอบ #2
คุณสามารถใช้วิธี filter ของอาร์เรย์เพื่อลบองค์ประกอบเฉพาะออกจากอาร์เรย์โดยไม่ทำให้สถานะเดิมเปลี่ยนแปลง
return state.filter(element => element !== action.payload);
ในบริบทของโค้ดของคุณ มันจะดูเหมือนประมาณนี้:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => item !== action.payload),
lastUpdated: Date.now()
})
คำตอบ #3
เมธอด Array.prototype.filter ของ ES6 จะคืนค่าอาร์เรย์ใหม่ที่มีรายการที่ตรงตามเกณฑ์ ดังนั้น ในบริบทของคำถามเดิม สิ่งนี้จะเป็น:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => action.payload !== item),
lastUpdated: Date.now()
})
คำตอบ #4
อีกหนึ่งรูปแบบของตัวลดค่า "DELETED" ที่ไม่เปลี่ยนแปลงสำหรับอาเรย์ที่มีวัตถุ:
const index = state.map(item => item.name).indexOf(action.name);
const stateTemp = [
...state.slice(0, index),
...state.slice(index + 1)
];
return stateTemp;
