Redux & RxJS มีความคล้ายคลึงกันหรือไม่


113

ฉันรู้ว่า Redux เป็น "การนำไปใช้งาน" ที่ดีกว่าของ Flux หรือดีกว่าที่บอกว่าเป็นการออกแบบใหม่เพื่อลดความซับซ้อนของสิ่งต่างๆ

ฉันเคยได้ยินเกี่ยวกับการเขียนโปรแกรมปฏิกิริยา (RxJS) มามากมาย แต่ฉันยังไม่ได้เรียนรู้

คำถามของฉันคือ: มีจุดตัด (อะไรที่เหมือนกัน) ระหว่างเทคโนโลยีทั้งสองนี้หรือไม่? ... หรือแตกต่างกันโดยสิ้นเชิง?

คำตอบ:


185

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

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

RxJS เป็นไลบรารีการเขียนโปรแกรมแบบปฏิกิริยา โดยปกติจะใช้เป็นเครื่องมือในการทำงานแบบอะซิงโครนัสใน JavaScript ให้สำเร็จ คิดว่าเป็นอีกทางเลือกหนึ่งของสัญญา


การเขียนโปรแกรมปฏิกิริยาเป็นกระบวนทัศน์ (วิธีการทำงานและความคิด) ที่มีการเปลี่ยนแปลงข้อมูลจะสังเกตได้จากระยะไกล ข้อมูลที่ไม่ได้มีการเปลี่ยนแปลงจากระยะไกล

นี่คือตัวอย่างของการเปลี่ยนแปลงจากระยะไกล :

// In the controller.js file
model.set('name', 'George');

รุ่นที่มีการเปลี่ยนแปลงจากตัวควบคุม

นี่คือตัวอย่างของการสังเกตจากระยะไกล :

// logger.js
store.subscribe(function (data) {
    console.log(data);
});

ใน Logger เราสังเกตการเปลี่ยนแปลงข้อมูลที่เกิดขึ้นใน Store (จากระยะไกล) และเขียนลงในคอนโซล


Redux ใช้ Reactive paradigm เพียงเล็กน้อย: Store จะตอบสนอง คุณไม่ได้ตั้งค่าเนื้อหาจากระยะไกล นั่นเป็นเหตุผลที่ไม่มีstore.set()ใน Redux Store สังเกตการกระทำจากระยะไกลและเปลี่ยนแปลงตัวเอง และ Store ช่วยให้ผู้อื่นสังเกตข้อมูลได้จากระยะไกล

RxJS ยังใช้กระบวนทัศน์แบบปฏิกิริยา แต่แทนที่จะเป็นสถาปัตยกรรมมันให้การสร้างแบบพื้นฐานObservablesเพื่อบรรลุรูปแบบ "การสังเกตจากระยะไกล" นี้

สรุปได้ว่าสิ่งที่แตกต่างกันมากสำหรับวัตถุประสงค์ที่แตกต่างกัน แต่แบ่งปันแนวคิดบางอย่าง


4
ไม่คุณไม่ควรใช้ร่วมกัน ผู้คนได้เลียนแบบ Redux โดยใช้ Rx Google ฉบับย่อจะหาตัวอย่างให้คุณ หากคุณต้องการใช้ Rx สำหรับ UI ที่ตอบสนองของคุณให้ชำระเงิน Cycle.js เฟรมเวิร์กของ Andre ฉันใช้มันเมื่อเร็ว ๆ นี้และมันยอดเยี่ยมมาก API ได้รับการเปลี่ยนแปลงอย่างมากเมื่อเร็ว ๆ นี้ แต่ฉันเชื่อว่าในที่สุดเขาก็เริ่มหยุดบางส่วนของมัน
Joel Dentici

17
ตามเอกสาร redux อย่างเป็นทางการ "พวกเขาทำงานร่วมกันได้ดีเยี่ยม"
galki

12
พวกเขาทำงานร่วมกันได้ดีมาก! มีมิดเดิลแวร์ Redux ที่เปิดโอกาสให้คุณใช้ RxJS และ Observables สำหรับการดำเนินการ Redux github.com/redux-observable/redux-observableนอกจากนี้ฉันเขียนบล็อกโพสต์เกี่ยวกับ How To: robinwieruch.de/redux-observable-rxjs
Robin Wieruch

1
กระบวนทัศน์ Redux ช่วยให้โค้ดเบสโครงการ Android ของฉันมีปฏิกิริยาตอบสนองมากขึ้น กระแสข้อมูลของเรามาจากปุ่มและฟิลด์อื่น ๆ เพื่ออัปเดตสถานะร่วมกับ RxJava ทำให้ความสามารถในการอ่านและประสิทธิภาพของเราสูงเกินไป ห้องสมุดเข้ากันได้ดีอย่างแน่นอนและประโยชน์ของพวกเขาคือไม่เข้าใจเรื่องภาษา
Kenny Worden

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

32

พวกเขาเป็นสิ่งที่แตกต่างกันมาก

RxJS สามารถใช้ในการทำ Reactive Programming และเป็นไลบรารีที่ละเอียดมากที่มีตัวดำเนินการมากกว่า 250 ตัว

และ Redux เป็นไปตามที่อธิบายไว้ใน github repo "Redux เป็นคอนเทนเนอร์สถานะที่คาดเดาได้สำหรับแอป JavaScript"

Redux เป็นเพียงเครื่องมือสำหรับจัดการสถานะในแอพ แต่ในการเปรียบเทียบคุณสามารถสร้างแอปเต็มรูปแบบได้ใน RxJS

หวังว่านี่จะช่วยได้ :)


3
คำตอบของคุณก็ดีเช่นกัน @cmdv ฉันไม่เห็นมันตอนที่ฉันเขียนของฉัน
André Staltz

4

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

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

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


2

เพื่อให้สั้น:

Redux:ฟลักซ์เป็นแรงบันดาลใจห้องสมุดที่ใช้สำหรับการบริหารจัดการของรัฐ

RxJS:เป็นไลบรารี Javascript อีกอันที่อิงตามปรัชญาการเขียนโปรแกรมแบบรีแอคทีฟซึ่งใช้เพื่อจัดการกับ "Streams" (Observables เป็นต้น) [อ่านเกี่ยวกับ Reactive Programming เพื่อทำความเข้าใจแนวคิด Stream]


1

ฉันแค่ต้องการเพิ่มความแตกต่างในทางปฏิบัติจากตอนที่ฉันใช้รหัส RxJS ที่ได้รับแรงบันดาลใจจาก Redux

ฉันแมปการกระทำแต่ละประเภทกับอินสแตนซ์หัวเรื่อง ส่วนประกอบ stateful แต่ละรายการจะมี Subject ที่ถูกแมปลงในฟังก์ชันตัวลด สตรีมตัวลดทั้งหมดจะรวมกับmergeแล้วscanส่งออกสถานะ ค่าเริ่มต้นถูกกำหนดไว้startWithก่อนหน้าไฟล์scan. ฉันใช้publishReplay(1)สำหรับรัฐ แต่อาจลบออกในภายหลัง

ฟังก์ชันการเรนเดอร์ตอบสนองบริสุทธิ์จะใช้เฉพาะที่ที่คุณสร้างข้อมูลเหตุการณ์โดยการส่งในผู้ผลิต / หัวเรื่องทั้งหมด

หากคุณมีส่วนประกอบย่อยคุณต้องอธิบายว่าสถานะเหล่านั้นรวมเป็นของคุณอย่างไร combineLatestอาจเป็นจุดเริ่มต้นที่ดีสำหรับสิ่งนั้น

ความแตกต่างที่โดดเด่นในการใช้งาน:

  • ไม่มีตัวกลางเพียงตัวดำเนินการ rxjs ฉันคิดว่านี่เป็นพลังและจุดอ่อนที่ใหญ่ที่สุด คุณยังสามารถยืมแนวคิดได้ แต่ฉันพบว่าเป็นการยากที่จะขอความช่วยเหลือจากชุมชนในเครือเช่น redux และ cycle.js เนื่องจากเป็นอีกหนึ่งโซลูชันที่กำหนดเอง นั่นเป็นเหตุผลที่ฉันต้องเขียน "ฉัน" แทน "เรา" ในข้อความนี้

  • ไม่มีสวิตช์ / เคสหรือสตริงสำหรับประเภทการดำเนินการ คุณมีวิธีแยกการกระทำแบบไดนามิกมากขึ้น

  • rxjs สามารถใช้เป็นเครื่องมือที่อื่นได้และไม่มีอยู่ในการจัดการของรัฐ

  • จำนวนผู้ผลิตน้อยกว่าประเภทการกระทำ (?) ฉันไม่แน่ใจเกี่ยวกับเรื่องนี้ แต่คุณสามารถมีปฏิกิริยาหลายอย่างในองค์ประกอบหลักที่ฟังส่วนประกอบย่อย นั่นหมายถึงรหัสที่จำเป็นน้อยกว่าและมีความซับซ้อนน้อยลง

  • คุณเป็นเจ้าของโซลูชัน ไม่จำเป็นต้องมีกรอบ ดีและไม่ดี คุณจะต้องเขียนกรอบของคุณเอง

  • เป็นแฟร็กทัลมากกว่ามากและคุณสามารถสมัครรับการเปลี่ยนแปลงจากแผนผังย่อยหรือหลายส่วนของโครงสร้างสถานะแอปได้อย่างง่ายดาย

    • เดาว่าการทำมหากาพย์เป็นเรื่องง่ายอย่างที่สามารถทำได้ง่ายเพียงใด? ง่ายมาก

ฉันยังทำงานเพื่อประโยชน์ที่ใหญ่กว่ามากซึ่งมีการอธิบายส่วนประกอบย่อยว่าเป็นสตรีม ซึ่งหมายความว่าเราไม่จำเป็นต้องรวมสถานะแม่และลูกในตัวลดเนื่องจากเราสามารถ ("just") รวมสถานะซ้ำ ๆ ตามโครงสร้างส่วนประกอบ

ฉันยังคิดเกี่ยวกับการข้ามการตอบสนองและไปกับ snabbdom หรืออย่างอื่นจนกว่า React จะจัดการสถานะปฏิกิริยาได้ดีขึ้น ทำไมเราต้องสร้างสถานะของเราขึ้นไปเพื่อทำลายมันผ่านอุปกรณ์ประกอบฉากอีกครั้ง? ดังนั้นฉันจะพยายามสร้างเวอร์ชัน 2 ของรูปแบบนี้ด้วย Snabbdom

นี่คือตัวอย่างข้อมูลขั้นสูง แต่มีขนาดเล็กที่ไฟล์ state.ts สร้างสตรีมสถานะ นี่คือสถานะขององค์ประกอบรูปแบบ ajax ซึ่งได้รับวัตถุของเขตข้อมูล (อินพุต) ที่มีกฎการตรวจสอบความถูกต้องและรูปแบบ css ในไฟล์นี้เราเพียงแค่ใช้ชื่อฟิลด์ (คีย์ออบเจ็กต์) เพื่อรวมสถานะของเด็กทั้งหมดเข้าในสถานะแบบฟอร์ม

export default function create({
  Observable,
  ajaxInputs
}) {
  const fieldStreams = Object.keys(ajaxInputs)
  .map(function onMap(fieldName) {
    return ajaxInputs[fieldName].state.stream
    .map(function onMap(stateData) {
      return {stateData, fieldName}
    })
  })

  const stateStream = Observable.combineLatest(...fieldStreams)
  .map(function onMap(fieldStreamDataArray) {
    return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) {
    acc[fieldStreamData.fieldName] = fieldStreamData.stateData
    return acc
  }, {})
  })

  return {
    stream: stateStream
  }
}

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


หนึ่งปีต่อมาฉันเพิ่งพบคำตอบของคุณและคิดว่ามันยังใช้ได้อยู่! ฉันทำสิ่งที่คล้ายกันและเห็นด้วยกับทุกประเด็นของคุณ แต่คำถามยังไงก็ได้: วันนี้คุณยังคิดเหมือนเดิมไหมหรือตั้งแต่นั้นเป็นต้นมา
Xceno

1
ฉันต้องการแก้ไขคำวิจารณ์เกี่ยวกับสวิตช์ / เคสและประเภทการกระทำใน Redux ฉันยังคงทำโค้ดเหมือนเดิม แต่พยายามทำงานเพื่อให้มันทำงานฝั่งเซิร์ฟเวอร์ เมื่อพูดถึง React code ฉันได้จัดการยูทิลเล็ก ๆ ที่ช่วยสร้างตัวลด / ตัวอัปเดต ฉันก็ยังคงทำแบบเดิม แต่ขัดขึ้นเล็กน้อย การเปลี่ยนแปลงที่ใหญ่ที่สุดคือฉันให้โหนดลีฟแต่ละโหนดสมัครสตรีมบน componentDidMount และยกเลิกการสมัคร componentDidUnmount ฉันต้องการรับชั้นบริการที่ตอบสนองเช่นกันที่ทำงานในส่วนหน้าและส่วนหลัง สร้างความก้าวหน้าที่นั่น
Marcus Rådell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.