ข้อเสียของการใช้ Redux แทน Flux [ปิด]


243

ฉันเพิ่งค้นพบRedux ทุกอย่างดูดี มี downside, gotcha หรือประนีประนอมของการใช้ Redux มากกว่า Flux หรือไม่? ขอบคุณ

คำตอบ:


411

เขียน Redux ที่นี่!

ฉันอยากจะบอกว่าคุณจะใช้การประนีประนอมต่อไปนี้:

  • คุณจะต้องเรียนรู้ที่จะหลีกเลี่ยงการกลายพันธุ์ Flux ไม่ได้ถูก จำกัด เกี่ยวกับการกลายพันธุ์ของข้อมูล แต่ Redux ไม่ชอบการกลายพันธุ์และแพคเกจเสริมมากมายที่ Redux คิดว่าคุณไม่เคยกลายพันธุ์ คุณสามารถบังคับใช้สิ่งนี้ได้กับแพ็คเกจ dev-only เช่นredux-immutable-state-invariant , ใช้Immutable.js , หรือเชื่อใจตัวเองและทีมของคุณในการเขียนโค้ดที่ไม่กลายพันธุ์ แต่มันเป็นสิ่งที่คุณต้องระวังและสิ่งนี้จำเป็นต้อง เป็นการตัดสินใจที่มีสติซึ่งยอมรับโดยทีมของคุณ

  • คุณจะต้องเลือกแพคเกจของคุณอย่างระมัดระวัง ในขณะที่ฟลักซ์อย่างชัดเจนไม่ได้พยายามที่จะแก้“ใกล้เคียง” ปัญหาเช่น/ ทำซ้ำยกเลิก , การติดตาหรือรูปแบบ , Redux มีจุดส่วนขยายเช่นมิดเดิลแวร์และเก็บเพิ่มและจะได้กลับกลายเป็นระบบนิเวศที่อุดมไปด้วย แต่หนุ่มสาว ซึ่งหมายความว่าแพ็คเกจส่วนใหญ่เป็นแนวคิดใหม่และยังไม่ได้รับปริมาณการใช้ที่สำคัญ คุณอาจต้องพึ่งพาบางสิ่งที่เห็นได้ชัดว่าเป็นความคิดที่ไม่ดีในอีกไม่กี่เดือนต่อมา แต่ก็ยังยากที่จะบอกได้

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

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


ดูเพิ่มเติมเกี่ยวกับคำตอบของฉันupsides ของการใช้ Redux


1
คำตอบที่ยอดเยี่ยม มีคำอธิบายง่ายๆหรือไม่ว่าเหตุใดการหลีกเลี่ยงการกลายพันธุ์ในรีดักซ์และแพ็คเกจเสริม?
rambossa

7
กล่าวโดยสรุปการกลายพันธุ์ทำให้ยากต่อการตรวจสอบว่าส่วนใดของรัฐเปลี่ยนเป็นวาดใหม่อย่างมีประสิทธิภาพเพียงบางส่วนของ UI ที่เปลี่ยนไป พวกเขาทำให้การแก้จุดบกพร่องยากขึ้นและห้องสมุดเช่นgithub.com/omnidan/redux-undoเป็นไปไม่ได้ ในที่สุดการเดินทางข้ามเวลาในgithub.com/gaearon/redux-devtoolsจะไม่ทำงานหากรัฐถูกเปลี่ยนแปลง
Dan Abramov

@DanAbramov การไม่เปลี่ยนรูปจะช่วยให้มีการวาดซ้ำที่มีประสิทธิภาพใน Redux ได้อย่างไร เช่นในการshallowEqualตรวจสอบปฏิกิริยาตอบสนองจะใช้ในการพิจารณาว่าสถานะเปลี่ยนไปหรือไม่ แต่มันสามารถถูกแทนที่ด้วย deepEqual หรือ JSON.stringify และเปรียบเทียบ ในที่สุดมันค่อนข้างมีประสิทธิภาพที่ต่ำกว่า - แต่เป็นการคำนวณที่บริสุทธิ์โดยไม่ต้องจัดการกับ DOM - เร็วพอ และในกรณีใด ๆ การแสดงผลตัวเองจะเหมือนกัน
amakhrov

@amakhrov deepEqual หรือ JSON.stringify ค่อนข้างช้า มันไม่ได้ "เร็วพอ" สำหรับแอปจริง ๆ โดยเฉพาะถ้าคุณเปรียบเทียบข้อมูลสำหรับทุกมุมมอง
Dan Abramov

โอเคเข้าใจแล้ว. เสียงที่เปลี่ยนไม่ได้ทำให้การตรวจสอบที่สกปรกมีประสิทธิภาพมากขึ้นแทนที่จะทำให้การวาดใหม่มีประสิทธิภาพมากขึ้น
amakhrov

37

ทั้ง Redux และ Flux จำเป็นต้องใช้รหัส boilerplate จำนวนมากเพื่อให้ครอบคลุมรูปแบบที่พบบ่อยโดยเฉพาะอย่างยิ่งที่เกี่ยวข้องกับการดึงข้อมูลแบบอะซิงโครนัส เอกสาร Redux แล้วมีไม่กี่คนของตัวอย่างสำหรับการลดสำเร็จรูป: http://redux.js.org/docs/recipes/ReducingBoilerplate.html คุณสามารถรับทุกสิ่งที่คุณต้องการจากห้องสมุด Flux เช่น Alt หรือ Fluxxor แต่ Redux ต้องการอิสระมากกว่าฟีเจอร์ นี่อาจเป็นข้อเสียสำหรับนักพัฒนาซอฟต์แวร์บางรายเนื่องจาก Redux ทำให้สมมติฐานบางอย่างเกี่ยวกับสถานะของคุณที่อาจถูกเพิกเฉยโดยไม่ตั้งใจ

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

ข้อจำกัดความรับผิดชอบ: ฉันย้ายจาก Flummox (การใช้ Flux ที่เป็นที่นิยม) ไปยัง Redux และ upside นั้นมีมากกว่าข้อเสียใด ๆ ฉันชอบเวทย์มนตร์น้อยกว่าในรหัสของฉัน เวทมนตร์น้อยลงมีค่าใช้จ่ายมากขึ้นเล็กน้อย แต่มันมีค่าใช้จ่ายน้อยมาก


16

ฟลักซ์และRedux . .

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


Redux กำลังสนับสนุนแนวคิดที่ไม่เปลี่ยนรูป

ทำไมไม่เปลี่ยนรูป?

มีเหตุผลสองสามข้อที่:
1. การเชื่อมโยงกัน - สถานะของร้านค้าจะเปลี่ยนไปตลอดเวลาโดยตัวลด
2. ผลการปฏิบัติงาน - เนื่องจากมันไม่เปลี่ยนรูป Redux จำเป็นต้องตรวจสอบว่าสถานะก่อนหน้า! == สถานะปัจจุบันและหากต้องการแสดงผล ไม่จำเป็นต้องวนลูปรัฐทุกครั้งเพื่อกำหนดเรนเดอร์
3. การดีบั๊ก - แนวคิดใหม่ที่ยอดเยี่ยมเช่นการแก้ไขข้อผิดพลาดในการเดินทางข้ามเวลาและการโหลดซ้ำร้อนแรง

UPDATE: ถ้าที่ไม่ได้รับการจูงใจพอที่ดูลีไบรอนพูดคุยที่ดีเกี่ยวกับการเชื่อมต่อผู้ใช้ไม่เปลี่ยนรูป

Redux ต้องการวินัยนักพัฒนาผ่าน codebase / libraries เพื่อรักษาความคิดนี้ คุณจะต้องตรวจสอบให้แน่ใจว่าคุณได้เลือกไลบรารีและเขียนรหัสด้วยวิธีที่ไม่แน่นอน

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

หลังจากบอกว่าฉันต้องยอมรับว่า Redux เป็นที่ที่ JS จะพัฒนาในอนาคต (สำหรับการเขียนบรรทัดเหล่านี้)


15

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


4

ฉันชอบใช้Reduxเพราะใช้ร้านหนึ่งซึ่งทำให้การจัดการของรัฐง่ายขึ้นเมื่อเทียบกับFluxและRedux DevToolsเป็นเครื่องมือที่มีประโยชน์มากซึ่งช่วยให้คุณเห็นสิ่งที่คุณทำกับรัฐของคุณด้วยข้อมูลที่มีประโยชน์และสอดคล้องกับเครื่องมือพัฒนา React

นอกจากนี้ยังReduxได้มีความยืดหยุ่นมากขึ้นโดยใช้กับกรอบนิยมอื่น ๆ เช่นเชิงมุม อย่างไรก็ตามเรามาดูกันว่า Redux แนะนำตัวเองเป็นเฟรมเวิร์กอย่างไร

Redux มีหลักการสามประการที่สามารถนำ Redux ได้ดีมากและเป็นความแตกต่างหลักระหว่าง Redux และ Flux ด้วย

แหล่งเดียวของความจริง

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

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

console.log(store.getState())

/* Prints
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/

สถานะเป็นแบบอ่านอย่างเดียว

วิธีเดียวที่จะเปลี่ยนสถานะคือการปล่อยการกระทำวัตถุที่อธิบายสิ่งที่เกิดขึ้น

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

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

การเปลี่ยนแปลงเกิดขึ้นกับฟังก์ชั่นแท้

ในการระบุวิธีการแปลงสภาพต้นไม้จากการกระทำคุณเขียน reducers แท้

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

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)

สำหรับข้อมูลเพิ่มเติมเยี่ยมชมที่นี่


0

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


-1

เท่าที่ฉันรู้การไหลของแรงบันดาลใจจากการไหล flux เป็นสถาปัตยกรรมอย่าง MVC (model view controller) facebook แนะนำฟลักซ์เนื่องจากปัญหาการขยายตัวเมื่อใช้ MVC ฟลักซ์จึงไม่ใช่การนำไปใช้มันเป็นเพียงแนวคิด จริง ๆ แล้วการเปลี่ยนแปลงคือการดำเนินการของฟลักซ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.