React-Redux: ควรเก็บสถานะส่วนประกอบทั้งหมดไว้ใน Redux Store


90

สมมติว่าฉันมีการสลับง่ายๆ:

เมื่อฉันคลิกปุ่มส่วนประกอบสีจะเปลี่ยนไปมาระหว่างสีแดงและสีน้ำเงิน

ฉันอาจจะบรรลุผลโดยการทำอะไรแบบนี้

index.js

Button: onClick={()=>{dispatch(changeColor())}}
Color: this.props.color ? blue : red

container.js

connect(mapStateToProps)(indexPage)

action_creator.js

function changeColor(){
 return {type: 'CHANGE_COLOR'}
}

reducer.js

switch(){
case 'CHANGE_COLOR':
return {color: true}

แต่นี่เป็นโค้ดจำนวนมากที่ต้องเขียนสำหรับบางสิ่งที่ฉันสามารถทำได้ใน 5 วินาทีด้วย jQuery บางคลาสและ css ...

ฉันเดาว่าสิ่งที่ฉันถามจริงๆคือฉันทำอะไรผิดที่นี่?


7
react-redux ไม่ได้ขายเป็นสิ่งที่สั้นกว่า jquery จำเป็นต้องมีรหัสบางอย่างเพื่อนำมาใช้งาน
zerkms

คำตอบ:


161

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

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

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

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


เฮ้ฉันรู้ว่าจะไม่มีคำตอบที่ชัดเจนสำหรับคำถามนี้ แต่ฉันคิดว่าตรรกะของคุณฟังดูดีมากที่นี่
l2silver

IMO ไม่ใช่คำตอบที่สมบูรณ์แบบ มันขึ้นอยู่กับ. การจัดเก็บสถานะ ui ไว้ในสถานะทำปฏิกิริยาจะทำให้การจัดเก็บ redux สะอาด แต่จะจบลงด้วยส่วนประกอบที่ไม่ทำงานซึ่งยากต่อการทดสอบ ในขณะที่การจัดเก็บสถานะ ui เป็นสถานะการตอบสนองจะเพิ่มความพยายามมากมายใน dev เนื่องจากเราต้องเขียนตัวลดพิเศษ อย่างไรก็ตามมีแพ็คเกจมากมายที่ช่วยให้คุณวางสถานะ ui ของคุณได้ง่ายขึ้นในการจัดเก็บ redux โปรดตรวจสอบredux.js.org/docs/faq/OrganizingState.htmlสำหรับรายละเอียดเพิ่มเติม
รอน

21

คำถามที่พบบ่อยของ Redux: การจัดระเบียบ
ส่วนนี้ของเอกสารทางการของ redux ตอบคำถามของคุณได้ดี

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

กฎทั่วไปบางประการในการพิจารณาว่าควรใส่ข้อมูลประเภทใดใน Redux:

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

7

เพื่อจุดประสงค์ในการไฮไลต์ลิงก์ที่ยอดเยี่ยมที่มีให้โดย @ AR7 และเนื่องจากลิงก์นั้นย้ายไปมาในขณะ:

ใช้ React สำหรับสถานะชั่วคราวที่ไม่สำคัญกับแอปทั่วโลกและไม่กลายพันธุ์ในรูปแบบที่ซับซ้อน ตัวอย่างเช่นการสลับในองค์ประกอบ UI บางอย่างสถานะการป้อนแบบฟอร์ม ใช้ Redux สำหรับสถานะที่มีความสำคัญทั่วโลกหรือกลายพันธุ์ในรูปแบบที่ซับซ้อน ตัวอย่างเช่นผู้ใช้ที่แคชไว้หรือแบบร่างของโพสต์

บางครั้งคุณอาจต้องการย้ายจากสถานะ Redux ไปเป็นสถานะ React (เมื่อจัดเก็บบางอย่างใน Redux จะอึดอัด) หรือในทางกลับกัน (เมื่อส่วนประกอบมากขึ้นจำเป็นต้องเข้าถึงบางสถานะที่เคยเป็นแบบโลคัล)

หลักการง่ายๆคือทำอะไรก็ได้ให้อึดอัดน้อยลง

Dan Abramov: https://github.com/reactjs/redux/issues/1287#issuecomment-175351978


-9

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

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

ด้วยเหตุผลด้านประสิทธิภาพคุณอาจต้องการถอยกลับไปthis.setState()หาสิ่งที่จะส่งการกระทำหลาย ๆ ครั้งซ้ำ ๆ ตัวอย่างเช่นการจัดเก็บสถานะของช่องป้อนข้อมูลใน Redux ทุกครั้งที่ผู้ใช้พิมพ์คีย์อาจส่งผลให้ประสิทธิภาพการทำงานต่ำ คุณสามารถแก้ปัญหานี้ได้โดยปฏิบัติเหมือนธุรกรรม: เมื่อการกระทำของผู้ใช้ "กระทำ" ให้บันทึกสถานะสุดท้ายใน Redux

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


การแก้ไขจุดบกพร่องที่ได้รับการปรับปรุงเป็นเป้าหมายที่มีประโยชน์และเป็นคุณสมบัติที่ดีของการทำซ้ำ แต่ฉันคิดว่าอัตราส่วนสัญญาณต่อเสียงรบกวนก็สำคัญเช่นกัน เราสามารถบันทึกทุกตัวแปรใน codebase ได้ แต่นั่นจะเป็นการเพิ่มโค้ดพิเศษจำนวนมากทำให้โค้ดจริงอ่านยากขึ้นและการบันทึกจะยากต่อการค้นหา ฉันคิดว่าเช่นเดียวกันกับการใช้ redux การมีสถานะทั้งหมดใน redux สามารถปรับปรุงการดีบักได้ แต่มีค่าใช้จ่ายในโค้ดเพิ่มเติมและ abstractions ที่ทำให้โค้ดอ่านยากขึ้นและทำให้งานดีบักบางอย่างยากขึ้น (และเมื่อเครื่องมือ dev redux ขัดข้องผลกำไรจากการดีบักจำนวนมากจะหายไป)
JD Sandifer

1
แล้วทำไมต้องใช้ Redux เลย? หากคุณไม่ใส่ทุกอย่างใน Redux คุณจะสูญเสียคุณสมบัติทั้งหมดเช่น devtools จริงๆมันคือทั้งหมดหรือไม่มีอะไร หากคุณใช้ setState () สำหรับเมนูแบบเลื่อนลงเช่นในคำตอบด้านบนของโพสต์นี้คุณจะไม่สามารถใช้ devtools เพื่อแก้ไขข้อบกพร่องใด ๆ ที่ผู้ใช้ของคุณอาจพบในเมนูแบบเลื่อนลง จะแย่กว่าเมื่อคุณใช้ setState () สำหรับการวางซ้อนเนื่องจากไม่มีวิธีการเดินทางข้ามเวลาก่อนและหลังการแสดงภาพซ้อนทับ โรย setState () ที่นี่และมีข้อผิดพลาดได้ง่ายเนื่องจาก dev ต้องคิดตลอดเวลาเกี่ยวกับสิ่งที่อาจพัง
kumar303

เป็นคำตอบที่เฉพาะเจาะจงมากขึ้นเข้าสู่ระบบตัวแปรทุกคนใน codebase ไม่ได้เป็นคำอุปมาที่เป็นประโยชน์ตั้งแต่คำถามที่เป็นเรื่องเกี่ยวกับว่าจะใช้หรือthis.setState() dispatch(action...)ไม่จำเป็นต้องใช้this.setState()ทุกที่ แต่เมื่อคุณต้องการคำแนะนำของฉันคือใช้ Redux แทน 99% ของเคสโดยลดลงเหลือthis.setState()1% ตามความกังวลด้านประสิทธิภาพ
kumar303

การบันทึกตัวแปรทุกตัวดูเหมือนว่าฉันจะคล้ายคลึงกับการใส่ทุกอย่างใน Redux และไม่สามารถมองเห็นได้อย่างเท่าเทียมกันตามกฎทั่วไป การปล่อยบางสิ่งออกจาก Redux ไม่ได้เป็นการลบล้างคุณลักษณะสำหรับทุกสิ่งที่อยู่ใน Redux ตราบใดที่สถานะถูกแยกออก คือฉันยังสามารถดีบักตรรกะการเรียก API ของฉันที่ถูกส่งผ่าน Redux แม้ว่าสถานะของกล่องการเลือกจะไม่ใช่ก็ตาม OP มีประเด็น - ต้องใช้รหัสเพิ่มเติมในหลาย ๆ ที่เพื่อใช้ Redux และบางทีนั่นอาจไม่เป็นธรรมในตัวอย่างเฉพาะที่ระบุไว้
JD Sandifer

คุณอาจไม่สามารถดีบักตรรกะ API ของคุณได้จริง นั่นคือประเด็นของฉัน มันยากมากที่จะคาดการณ์สถานการณ์ที่คุณจะหยุดพักการเดินทางข้ามเวลาดังนั้นจึงเป็นการดีกว่าเพียงแค่ใส่สถานะทั้งหมด (รวมถึงสถานะกล่องเลือก) ใน Redux จนกว่าจะมีปัญหาด้านประสิทธิภาพ
kumar303
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.