วิธีลดโค้ดสำเร็จรูป

เราจะไม่อธิบายที่นี่ว่าโครงสร้างรีดักซ์มีโครงสร้างอย่างไรและทำงานอย่างไร คุณควรรู้ว่ามันใช้การดำเนินการและตัวลดเพื่อจัดการสถานะ และคนส่วนใหญ่มักจะใช้ตัวเลือกเพื่ออ่านสถานะจากรีดักซ์

บทนำ

Redux นั้นดีในการจัดการสถานะของคุณ แต่สามารถขยายไปสู่โค้ดสำเร็จรูปจำนวนมากได้อย่างง่ายดาย แม้ว่าคุณจะพยายามจัดการสถานะสำหรับสิ่งต่าง ๆ ที่มีกรณีการใช้งานที่คล้ายกัน แต่คุณก็ต้องดำเนินการและลดขนาดสิ่งเหล่านั้น

มีกฎง่ายๆ ประการหนึ่งที่ฉันชอบปฏิบัติตามเมื่อทำงานกับโปรเจ็กต์ react-redux หากคุณใช้ redux ให้ใช้มันทุกที่! อย่าทำให้โปรเจ็กต์ของคุณยุ่งเหยิงด้วยบางส่วนที่ใช้สถานะส่วนประกอบและส่วนอื่นๆ ที่ใช้ Redux Redux ควรเป็น "แหล่งความจริงเดียว" ของคุณ อย่าผสมกับ setState ชิ้นส่วน/ส่วนประกอบเดียวที่สามารถใช้สถานะส่วนประกอบได้คือแม่มดเหล่านั้นสามารถนำกลับมาใช้ใหม่ในโปรเจ็กต์ที่ไม่ใช้ Redux สิ่งเหล่านั้นไม่ควรมีการติดต่อกับตรรกะการสมัครของคุณ

ปัญหา

เมื่อคำนึงถึงเรื่องนั้นแล้ว ฉันจึงตกอยู่ในสถานการณ์ที่แปลกประหลาด ในโครงการทั้งหมดของฉัน ฉันใช้ไลบรารี Material-UI มันใช้ส่วนประกอบเช่น TextFields, Togglers, Dialogs ฯลฯ ที่ได้รับคุณสมบัติ ตัวอย่างที่ดีอย่างหนึ่งคือกล่องโต้ตอบ โดยจะจัดการเองว่าจะจัดสไตล์อย่างไรหากเปิดหรือปิด แต่เราตัดสินใจด้วยคุณสมบัติว่าควรเปิดหรือปิดเมื่อใด เนื่องจากสถานะว่ากล่องโต้ตอบเปิดอยู่หรือไม่เชื่อมโยงกับตรรกะแอปพลิเคชันของฉัน จึงต้องได้รับการจัดการโดย Redux

เพราะฉันใช้ Dialog ใน 90% เพื่อแสดงคำเตือนการลบ เช่น “คุณต้องการลบรายการ/บริษัท/บทความนี้ จริงๆ เหรอ..?” การเขียนการดำเนินการและตัวลดการลบแต่ละครั้งอาจเป็นเพียงความบ้าคลั่ง ดังนั้นการเขียนการดำเนินการเดียวและตัวลดขนาดเพื่อจัดการสถานะกล่องโต้ตอบทั้งหมดจึงเป็นโซลูชันที่เหมาะสมสำหรับฉัน มันเป็นตัวลดขนาดที่ง่ายมากที่จะจัดเก็บสำหรับแต่ละกล่องโต้ตอบไม่ว่าจะเปิดอยู่หรือไม่ก็ตาม

นี่คือรหัสการกระทำทั้งหมด:

import * as types from './types';
export function setDialogIsOpen(id, isOpen){
  return {
    type: types.ON_DIALOG_OPEN_CHANGED,
    id,
    isOpen
  };
}

และนี่คือโค้ดตัวลดทั้งหมด:

import * as types from './types';
export default function dialogs(state={}, action){
switch (action.type) {
    case types.ON_DIALOG_OPEN_CHANGED:
    return {...state, [action.id]: action.isOpen};
    default:
    return state;
  }
}

ด้วยเหตุนี้ ฉันสามารถจัดการสถานะ isOpen สำหรับการโต้ตอบที่ไม่มีที่สิ้นสุดในแอปพลิเคชันของฉันโดยแยกพวกมันด้วยชื่อหรือรหัส ฉันมีวิธีแก้ปัญหาที่ดีและมีประโยชน์

ในการรับสถานะ isOpen ไปยังองค์ประกอบกล่องโต้ตอบของฉัน ฉันแค่ต้องตรวจสอบดังนี้:

<Dialog
   title={intl.formatMessage({id: 'delete_task_title'})}
   actions={actions}
   modal={false}
   open={dialogs.delete_task===true}
   onRequestClose={this.handleClose}>
   {intl.formatMessage({id: 'delete_task_message'})}
</Dialog>

คุณสังเกตเห็นว่าเช็คทั้งหมดคือ dialogs.delete_task===true เฉพาะในกรณีที่ delete_task เป็น true กล่องโต้ตอบจะเปิดขึ้น หากไม่ได้กำหนดหรือเป็นเท็จก็จะถูกปิด

เรามีวิธีแก้ปัญหาง่ายๆ สำหรับสถานะของกล่องโต้ตอบ แต่จะเป็นอย่างไรกับสถานะ "เรียบง่าย" อื่นๆ เช่น งานปัจจุบัน แสดงหรือซ่อน div รหัสแถวที่เลือก ฯลฯ ... ทุกกรณีที่คุณต้องการจัดเก็บเพียงค่าที่เรียบง่าย

สารละลาย

วิธีแก้ไขเป็นแบบเดียวกับที่ฉันใช้สำหรับกล่องโต้ตอบ แต่เปลี่ยนชื่อ ;)

การดำเนินการ:

import * as types from './types';
export function setSimpleValue(id, value){
  return {
    type: types.ON_SIMPLE_VALUE_CHANGED,
    id,
    value
  };
}

ตัวลด:

import * as types from './types';
export default function simpleValues(state={}, action){
switch (action.type) {
    case types.ON_SIMPLE_VALUE_CHANGED:
    return {...state, [action.id]: action.value};
    default:
    return state;
  }
}

มันทำงานเหมือนวิธีแก้ปัญหาของกล่องโต้ตอบ แต่ด้วยการเปลี่ยนชื่อคุณรู้ว่ามันเป็นเพียงการเก็บค่าง่ายๆ ควรใช้ เฉพาะ สำหรับค่า "แบบง่าย"! เมื่อเก็บค่าเดี่ยวและค่าธรรมดาที่สามารถมีค่าได้เพียงค่าเดียวหรือไม่มีหรือเป็นได้เพียง trueหรือ false ทันทีที่อาร์เรย์มีความซับซ้อน ค่าหลายค่าคุณควรแยกการดำเนินการและตัวลด

ค่าอย่างง่ายทั้งหมดจะถูกคั่นด้วยชื่อหรือรหัส มันง่ายที่จะใช้วิธีแก้ปัญหาประเภทนี้ แต่คุณมักจะมีความเสี่ยงที่จะพิมพ์ผิด และการทำซ้ำตัวระบุชื่อ/รหัสอาจมีผลข้างเคียงและข้อผิดพลาดแปลกๆ

ฉันอยากจะแนะนำให้ใช้ในระยะเริ่มต้นของการใช้งานจนกว่าคุณจะมั่นใจ 100% ว่าคุณต้องการการดำเนินการและตัวลดประเภทใด มันมีประโยชน์มากที่จะสร้างต้นแบบง่ายๆ โดยไม่ต้องสร้างการดำเนินการและตัวลดขนาด

วิริยะ

หากคุณใช้ไลบรารีถาวร ก็มีวิธีแก้ไขปัญหาที่ "ง่าย" เช่นกัน เพียงสร้างการดำเนินการและตัวลดที่เปลี่ยนชื่อเป็น persistentValues และใช้รหัสเดียวกันกับการเปลี่ยนชื่อ ไลบรารีถาวรส่วนใหญ่อนุญาตให้คุณกำหนดรายการขาว/ดำเพื่อกำหนดว่าส่วนแม่มดของรัฐของคุณควรจะคงอยู่หรือไม่ เพียงใส่ simpleValues ลงในบัญชีดำหรือ persistentValues ลงในบัญชีขาว

การสาธิต

หากคุณสนใจว่าทั้งหมดนี้ทำงานอย่างไร คุณสามารถดูได้ในแอปพลิเคชันสาธิตที่ใช้ react, redux และ firebase: ReactMostWanted