เครื่องมือการจัดการสถานะปฏิกิริยาที่ดีที่สุดสำหรับแอปพลิเคชันระดับองค์กร
เผยแพร่แล้ว: 2022-03-11นักพัฒนาแอปพลิเคชัน React ระดับองค์กรทราบดีว่าการจัดการสถานะมีความสำคัญต่อประสบการณ์ผู้ใช้ปลายทางที่สอดคล้องกันอย่างไร
อย่างไรก็ตาม ผู้ใช้ไม่ใช่คนเดียวที่ได้รับผลกระทบจากการจัดการของรัฐ นักพัฒนา React สร้างและรักษาสถานะ พวกเขาต้องการการจัดการสถานะที่เรียบง่าย ขยายได้ และเป็นปรมาณู React ได้ย้ายไปในทิศทางนี้โดยแนะนำตะขอ
ปัญหาอาจเกิดขึ้นเมื่อมีการแบ่งปันสถานะระหว่างองค์ประกอบต่างๆ วิศวกรต้องหาเครื่องมือและไลบรารีที่เหมาะสมกับความต้องการของตน แต่ในขณะเดียวกันก็ต้องมีคุณสมบัติตรงตามมาตรฐานระดับสูงที่จำเป็นสำหรับแอประดับองค์กร
ในบทความนี้ ผมจะวิเคราะห์และเปรียบเทียบไลบรารีที่ได้รับความนิยมมากที่สุด และเลือกไลบรารี่ที่เหมาะสมที่สุดสำหรับการจัดการสถานะในแอปพลิเคชันระดับองค์กร
ความสามารถในการจัดการสถานะปฏิกิริยาในตัว
React มีเครื่องมือที่ยอดเยี่ยมสำหรับการให้ข้อมูลในหลายองค์ประกอบ เป้าหมายหลักของบริบทคือการหลีกเลี่ยงการเจาะเสา เป้าหมายของเราคือการจัดหาเครื่องมือที่ใช้งานง่ายเพื่อจัดการสถานะในสถานการณ์ต่างๆ ที่มีแนวโน้มว่าจะพบในแอปพลิเคชันระดับองค์กร: การอัปเดตบ่อยครั้ง การออกแบบใหม่ การแนะนำคุณสมบัติใหม่ และอื่นๆ
แม้ว่าทั้งหมดนี้เป็นไปได้ในทางทฤษฎีกับบริบท แต่ก็ต้องการโซลูชันที่กำหนดเองซึ่งต้องใช้เวลาในการตั้งค่า สนับสนุน และปรับให้เหมาะสม ข้อได้เปรียบเพียงอย่างเดียวของบริบทคือมันไม่ได้ขึ้นอยู่กับไลบรารีของบุคคลที่สาม แต่นั่นไม่สามารถเกินดุลความพยายามในการรักษาแนวทางนี้
นอกจากนี้ Sebastian Markbage สมาชิกในทีม React ได้กล่าวว่า Context API ใหม่ไม่ได้สร้างและปรับให้เหมาะสมสำหรับการอัปเดตความถี่สูง แต่สำหรับการอัปเดตความถี่ต่ำเช่นการอัปเดตธีมและการจัดการการตรวจสอบ
การตรวจสอบห้องสมุดที่มีอยู่
มีเครื่องมือการจัดการสถานะมากมายบน GitHub (เช่น Redux, MobX, Akita, Recoil และ Zusstand) อย่างไรก็ตาม การพิจารณาแต่ละรายการจะนำไปสู่การค้นคว้าและเปรียบเทียบอย่างไม่รู้จบ นั่นเป็นเหตุผลที่ฉันจำกัดการเลือกของฉันให้เหลือเพียงคู่แข่งหลักสามรายโดยพิจารณาจาก ความนิยม การใช้งาน และ การดูแลรักษา
เพื่อให้การเปรียบเทียบชัดเจน ฉันจะใช้แอตทริบิวต์คุณภาพต่อไปนี้:
- การใช้งาน
- การบำรุงรักษา
- ผลงาน
- ความสามารถในการทดสอบ
- ความสามารถในการปรับขนาด (ทำงานได้อย่างมีประสิทธิภาพเช่นเดียวกันในสถานะที่ใหญ่กว่า)
- ความสามารถในการปรับเปลี่ยนได้
- การนำกลับมาใช้ใหม่
- ระบบนิเวศ (มีเครื่องมือช่วยเหลือที่หลากหลายเพื่อขยายการทำงาน)
- ชุมชน (มีผู้ใช้จำนวนมากและคำถามของพวกเขาได้รับคำตอบบนเว็บ)
- การพกพา (สามารถใช้กับไลบรารี/เฟรมเวิร์กอื่นที่ไม่ใช่ React)
Redux
Redux เป็นคอนเทนเนอร์ของรัฐที่สร้างขึ้นในปี 2558 ซึ่งได้รับความนิยมอย่างมากเนื่องจาก:
- ไม่มีทางเลือกอื่นอย่างจริงจังเมื่อเปิดตัว
- มันให้การแยกระหว่างรัฐและการกระทำ
- เวทมนตร์
react-reduxเปิดใช้งานการเชื่อมต่อสถานะตรงไปตรงมา - ผู้ร่วมสร้างห้องสมุดคือผู้พัฒนา Facebook และ Dan Abramov สมาชิกในทีมหลักของ React
คุณมี ร้านค้าระดับโลก ที่มีข้อมูลของคุณอยู่ เมื่อใดก็ตามที่คุณต้องการอัปเดตร้านค้า คุณต้องส่ง การดำเนินการ ไปที่ ตัวลด ตัวลดจะอัปเดตสถานะในลักษณะที่ไม่เปลี่ยนรูปทั้งนี้ขึ้นอยู่กับประเภทการดำเนินการ
ในการใช้ Redux กับ React คุณจะต้องสมัครสมาชิกส่วนประกอบเพื่ออัพเดตร้านค้าผ่าน react-redux
ตัวอย่าง Redux API
ส่วนพื้นฐานของ Redux ใน codebase ที่ทำให้แตกต่างจากเครื่องมืออื่นๆ คือ สไลซ์ มีตรรกะของการกระทำและตัวลดทั้งหมด
CodeSandbox
// slices/counter.js import { createSlice } from "@reduxjs/toolkit"; export const slice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; } } }); export const actions = slice.actions; export const reducer = slice.reducer; // store.js import { configureStore } from "@reduxjs/toolkit"; import { reducer as counterReducer } from "./slices/counter"; export default configureStore({ reducer: { counter: counterReducer } }); // index.js import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import App from './App' import store from './store' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ) // App.js import React from "react"; import { useSelector, useDispatch } from "react-redux"; import { actions } from "./slices/counter"; const App = () => { const count = useSelector((state) => state.counter.value); const dispatch = useDispatch(); return ( <div> <div> <button onClick={() => dispatch(actions.increment())}>Increment</button> <span>{count}</span> <button onClick={() => dispatch(actions.decrement())}>Decrement</button> </div> </div> ); }; export default App;คุณสมบัติคุณภาพ
- การใช้งาน Redux กลายเป็นเรื่องง่ายด้วยการแนะนำแพ็คเกจชุดเครื่องมืออย่างเป็นทางการ คุณสร้างสไลซ์ (การรวมกันของสถานะเริ่มต้น ตัวลด และการดำเนินการ) ส่งต่อไปยังร้านค้า และเข้าถึงในส่วนประกอบผ่านตะขอ
- การบำรุงรักษา Redux เป็นเรื่องง่าย ไม่จำเป็นต้องมีความรู้อย่างลึกซึ้งเพื่อทำความเข้าใจวิธีปรับปรุงหรือซ่อมแซมบางสิ่ง
- ประสิทธิภาพการทำงาน ผู้มีอิทธิพลด้านประสิทธิภาพหลักกับ Redux คือวิศวกรซอฟต์แวร์ Redux เป็นเครื่องมือที่ตรงไปตรงมาโดยไม่มีตรรกะอะไรมาก หากคุณเห็นว่าการอัปเดตสถานะช้า คุณสามารถทำตามคำแนะนำอย่างเป็นทางการเพื่อทำให้อัปเดตเร็วขึ้นได้
- ความสามารถใน การทดสอบ Redux ประกอบด้วยฟังก์ชันล้วนๆ (การกระทำและตัวลดขนาด) ทำให้เหมาะสำหรับการทดสอบหน่วย นอกจากนี้ยังมีกลไกในการเขียนการทดสอบการรวมที่ร้านค้า การดำเนินการ และตัวลดการทำงานร่วมกัน
- ความสามารถใน การปรับ ขนาด ตามค่าเริ่มต้น Redux มีสถานะเดียว ทำให้ปรับขนาดได้ยาก อย่างไรก็ตาม มีไลบรารี redux-dynamic-modules ที่ช่วยให้สามารถสร้างตัวลดโมดูลและมิดเดิลแวร์ได้
- การ ปรับเปลี่ยน การปรับแต่ง Redux เป็นเรื่องง่ายเพราะรองรับมิดเดิลแวร์
- การนำกลับมาใช้ ใหม่ Redux เป็น framework ที่ไม่เชื่อเรื่องพระเจ้า ดังนั้นจึงสามารถใช้ซ้ำได้ดีมาก
- ระบบนิเวศ . Redux นำเสนอระบบนิเวศขนาดยักษ์ของส่วนเสริม ไลบรารี และเครื่องมือที่เป็นประโยชน์
- ชุมชน . Redux ซึ่งเป็นไลบรารีการจัดการของรัฐที่เก่าแก่ที่สุดในการเปรียบเทียบของเรา ได้รวบรวมชุมชนขนาดใหญ่ที่มีฐานความรู้ที่สำคัญ มีคำถามประมาณ 30,000 (~ 19,000 คำตอบ) พร้อมแท็ก
reduxใน Stack Overflow - ชีพจร . Redux ได้รับการปรับปรุงและบำรุงรักษาอย่างสม่ำเสมอ
MobX
MobX เป็นห้องสมุดที่ค่อนข้างเก่าอีกแห่งที่มีดาว 23,000 ดวงบน GitHub สิ่งที่ทำให้แตกต่างจาก Redux คือเป็นไปตามกระบวนทัศน์ OOP และใช้สิ่งที่สังเกตได้ MobX ถูกสร้างขึ้นโดย Michel Weststrate และขณะนี้ได้รับการดูแลโดยกลุ่มผู้ที่ชื่นชอบโอเพ่นซอร์สด้วยความช่วยเหลือจาก Mendix ในบอสตัน
ใน MobX คุณสร้างคลาส JavaScript ด้วยการเรียก makeObservable ภายใน Constructor ซึ่งเป็นที่ เก็บที่สังเกตได้ ของคุณ (คุณสามารถใช้ @observable decorator ถ้าคุณมีตัวโหลดที่เหมาะสม) จากนั้นคุณประกาศคุณสมบัติ (สถานะ) และวิธีการ ( การกระทำ และ ค่าที่คำนวณได้ ) ของคลาส ส่วนประกอบสมัครรับข้อมูลจากร้านค้าที่สังเกตได้นี้เพื่อเข้าถึงสถานะ ค่าที่คำนวณได้ และการดำเนินการ
คุณสมบัติที่สำคัญอีกประการของ MobX คือการกลายพันธุ์ อนุญาตให้อัปเดตสถานะอย่างเงียบ ๆ ในกรณีที่คุณต้องการหลีกเลี่ยงผลข้างเคียง
ตัวอย่าง MobX API
คุณลักษณะเฉพาะของ MobX คือคุณสร้างคลาส ES6 ที่เกือบจะบริสุทธิ์ด้วยเวทมนตร์ทั้งหมดที่ซ่อนอยู่ภายใต้ประทุน ต้องใช้โค้ดเฉพาะของไลบรารีน้อยกว่าเพื่อรักษาสมาธิในตรรกะ
CodeSandbox
// stores/counter.js import { makeAutoObservable } from "mobx"; class CounterStore { value = 0; constructor() { makeAutoObservable(this); } increment() { this.value += 1; } decrement() { this.value -= 1; } } export default CounterStore; // index.js import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "mobx-react"; import App from "./App"; import CounterStore from "./stores/counter"; ReactDOM.render( <Provider counter={new CounterStore()}> <App /> </Provider>, document.getElementById("root") ); // App.js import React from "react"; import { inject, observer } from "mobx-react"; const App = inject((stores) => ({ counter: stores.counter }))( observer(({ counter }) => { return ( <div> <div> <button onClick={() => counter.increment()}>Increment</button> <span>{counter.value}</span> <button onClick={() => counter.decrement()}>Decrement</button> </div> </div> ); }) ); export default App;คุณสมบัติคุณภาพ
- การใช้งาน ร้านค้าที่สังเกตได้คือจุดเริ่มต้นเดียวสำหรับการจัดการของรัฐ มันทำให้การใช้งาน MobX เป็นเรื่องง่ายเพราะคุณมีที่เดียวในการแก้ไข
- การบำรุงรักษา มันเป็นข้อเสียอย่างมาก หากไม่มีความรู้เกี่ยวกับ RxJS API คุณจะไม่สามารถบรรลุผลลัพธ์ที่ต้องการได้ การใช้ MobX ในทีมที่มีคุณสมบัติไม่ดีอาจนำไปสู่ปัญหาความไม่สอดคล้องกันของรัฐ
- ประสิทธิภาพการทำงาน MobX ประกอบด้วยร้านค้าอิสระและช่วยให้คุณสามารถสมัครสมาชิกร้านเดียวที่คุณต้องการ มันมีประสิทธิภาพมาก
- ความสามารถใน การทดสอบ ร้านค้าที่สังเกตได้คือออบเจ็กต์ JavaScript ธรรมดาที่มีฟังก์ชันตอบโต้ที่ซ่อนอยู่ภายใน การทดสอบเหมือนกับคลาส JavaScript อื่นๆ
- ความสามารถใน การปรับ ขนาด ร้านค้าที่สังเกตได้จะถูกแยกออกอย่างมีเหตุมีผล ไม่มีปัญหาในการปรับขนาด MobX
- การ ปรับเปลี่ยน MobX อนุญาตให้สร้างสิ่งที่สังเกตได้เองพร้อมพฤติกรรมที่ปรับเปลี่ยน นอกจากนี้ยังมีแนวคิดที่เรียกว่าปฏิกิริยา ปฏิกิริยาจำลองผลข้างเคียงโดยอัตโนมัติ สิ่งเหล่านี้ทำให้ MobX ปรับแต่งได้มาก
- การนำกลับมาใช้ ใหม่ MobX นั้นไม่เชื่อเรื่องพระเจ้าของเฟรมเวิร์ก ดังนั้นจึงสามารถใช้ซ้ำได้ดีมาก
- ระบบนิเวศ . มีส่วนขยายหลายร้อยรายการสำหรับ MobX
- ชุมชน . MobX มีแฟน ๆ ที่ทุ่มเทมากมาย มีคำถามประมาณ 1,600 (~ 1,000 คำตอบ) พร้อมแท็ก
mobxบน Stack Overflow - ชีพจร . MobX ได้รับการอัปเดตและบำรุงรักษาอย่างสม่ำเสมอ
หดตัว
การหดตัวเป็นผู้มาใหม่ซึ่งเป็นลูกสมุนล่าสุดของทีม React แนวคิดพื้นฐานที่อยู่เบื้องหลังคือการนำคุณลักษณะ React ที่ขาดหายไปไปใช้อย่างง่าย เช่น สถานะที่ใช้ร่วมกันและข้อมูลที่ได้รับ

คุณอาจสงสัยว่าเหตุใดจึงมีการตรวจสอบไลบรารีทดลองสำหรับโครงการระดับองค์กร อย่างแรกเลย Recoil เป็นหนึ่งในหัวข้อที่มีคนพูดถึงมากที่สุดในชุมชน React ในขณะนี้ ประการที่สอง Recoil ได้รับการสนับสนุนโดย Facebook และใช้ในแอพพลิเคชั่นบางตัวแล้ว ซึ่งหมายความว่ามันจะกลายเป็นเวอร์ชันที่เสถียรในบางจุด ในที่สุด มันเป็นวิธีการใหม่ทั้งหมดสำหรับการแชร์สถานะใน React และฉันแน่ใจว่าแม้ว่าการหดตัวจะถูกเลิกใช้ แต่ก็ยังมีเครื่องมืออื่นที่เป็นไปตามเส้นทางเดียวกัน
การหดตัวสร้างขึ้นจากสองเงื่อนไข: atom และ selector อะตอมเป็นชิ้นส่วนของรัฐที่ใช้ร่วมกัน ส่วนประกอบสามารถสมัครสมาชิกอะตอมเพื่อรับ/ตั้งค่า
ดังที่คุณเห็นในภาพ เฉพาะส่วนประกอบที่สมัครรับข้อมูลเท่านั้นที่จะแสดงผลใหม่เมื่อค่ามีการเปลี่ยนแปลง มันทำให้การหดตัวมีประสิทธิภาพมาก
สิ่งที่ดีอีกอย่างที่ Recoil มีให้ตั้งแต่แกะกล่องคือ ตัวเลือก ตัวเลือกคือค่าที่รวบรวมจากอะตอมหรือตัวเลือกอื่นๆ สำหรับผู้บริโภค ไม่มีความแตกต่างระหว่างอะตอมและซีเล็คเตอร์ พวกเขาเพียงแค่สมัครใช้งานชิ้นส่วนที่มีปฏิกิริยาตอบสนองและใช้งาน
เมื่อใดก็ตามที่มีการเปลี่ยนแปลงอะตอม/ตัวเลือก ตัวเลือกที่ใช้ (เช่น สมัครเป็นสมาชิก) จะถูกประเมินใหม่
ตัวอย่าง Recoil API
รหัสของ Recoil นั้นแตกต่างจากคู่แข่งมาก มันขึ้นอยู่กับ React hooks และเน้นที่โครงสร้างสถานะมากกว่าการกลายพันธุ์สถานะนี้
CodeSandbox
// atoms/counter.js import { atom } from "recoil"; const counterAtom = atom({ key: "counter", default: 0 }); export default counterAtom; // index.js import React from "react"; import ReactDOM from "react-dom"; import { RecoilRoot } from "recoil"; import App from "./App"; ReactDOM.render( <RecoilRoot> <App /> </RecoilRoot>, document.getElementById("root") ); // App.js import React from "react"; import { useRecoilState } from "recoil"; import counterAtom from "./atoms/counter"; const App = () => { const [count, setCount] = useRecoilState(counterAtom); return ( <div> <div> <button onClick={() => setCount(count + 1)}>Increment</button> <span>{count}</span> <button onClick={() => setCount(count - 1)}>Decrement</button> </div> </div> ); }; export default App;คุณสมบัติคุณภาพ
- การใช้งาน การหดตัวเป็นหนึ่งในเครื่องมือที่ง่ายที่สุดในการใช้งานเพราะมันทำงานเหมือนกับ
useStateใน React - การบำรุงรักษา สิ่งที่คุณต้องทำใน Recoil คือการรักษาตัวเลือกและขอเกี่ยวภายในส่วนประกอบ—ให้คุณค่ามากขึ้น, ต้นแบบน้อยลง
- ประสิทธิภาพการทำงาน Recoil สร้าง state tree นอก React ต้นไม้ประจำสถานะช่วยให้คุณได้รับและฟังสิ่งที่คุณต้องการ ไม่ใช่การเปลี่ยนแปลงของต้นไม้ทั้งต้น นอกจากนี้ยังปรับให้เหมาะสมอย่างดีภายใต้ประทุน
- ความสามารถใน การทดสอบ การหดตัวเป็นกลไกสำหรับการทดสอบอะตอมและตัวเลือก
- ความสามารถใน การปรับ ขนาด สถานะที่แยกออกเป็นชิ้นส่วนอิสระหลายส่วนทำให้เป็นผู้เล่นที่ดีในด้านความสามารถในการปรับขนาด
- การ ปรับเปลี่ยน การหดตัวมีหน้าที่ในการจัดเก็บค่าและการรวมเท่านั้น ไม่มีการไหลของข้อมูลจึงสามารถปรับแต่งได้อย่างง่ายดาย
- การนำกลับมาใช้ ใหม่ การหดตัวขึ้นอยู่กับ React ไม่สามารถใช้ซ้ำที่อื่นได้
- ระบบนิเวศ . ไม่มีระบบนิเวศสำหรับการหดตัวในขณะนี้
- ชุมชน . การหดตัวนั้นสดเกินไปที่จะมีชุมชนขนาดใหญ่ มีคำถามประมาณ 70 ข้อพร้อมแท็ก
recoiljsใน Stack Overflow - ชีพจร . การหดตัวมีการอัปเดตไม่บ่อยนัก (ผ่านไปหกเดือนระหว่างการอัปเดตล่าสุดสองครั้ง) นอกจากนี้ยังมีปัญหาเปิดมากมายใน GitHub
การเลือกเครื่องมือการจัดการสถานะปฏิกิริยาที่เหมาะสม
ไลบรารีการจัดการสถานะทั่วโลกของ React เหล่านี้ซ้อนกันอย่างไรเมื่อพูดถึงแอพระดับองค์กร
การหดตัวนั้นยังเด็กและสดใหม่ แต่ไม่มีชุมชนหรือระบบนิเวศในขณะนี้ แม้ว่า Facebook จะดำเนินการกับมันและ API ดูเหมือนจะมีแนวโน้มดี แต่แอปพลิเคชัน React ขนาดใหญ่ก็ไม่สามารถพึ่งพาไลบรารี่ที่มีการสนับสนุนชุมชนที่อ่อนแอได้ นอกจากนี้ยังเป็นการทดลองทำให้ไม่ปลอดภัยมากยิ่งขึ้น ไม่ใช่ตัวเลือกที่ดีสำหรับแอปพลิเคชัน React สำหรับองค์กรในปัจจุบัน แต่ควรจับตาดูให้ดี
MobX และ Redux ไม่ได้แชร์ปัญหาเหล่านี้และผู้เล่นรายใหญ่ส่วนใหญ่ในตลาดก็ใช้ปัญหาเหล่านี้ สิ่งที่ทำให้พวกเขาแตกต่างจากกันคือเส้นโค้งการเรียนรู้ MobX ต้องการความเข้าใจพื้นฐานเกี่ยวกับการเขียนโปรแกรมเชิงโต้ตอบ หากวิศวกรที่เกี่ยวข้องในโครงการไม่มีทักษะเพียงพอ แอปพลิเคชันอาจลงเอยด้วยรหัสที่ไม่สอดคล้องกัน ปัญหาด้านประสิทธิภาพ และเวลาในการพัฒนาที่เพิ่มขึ้น MobX เป็นที่ยอมรับและจะตอบสนองความต้องการของคุณหากทีมของคุณตระหนักถึงปฏิกิริยา
Redux มีปัญหาบางอย่างเช่นกัน ส่วนใหญ่เกี่ยวกับความสามารถในการปรับขนาดและประสิทธิภาพ อย่างไรก็ตาม ต่างจาก MobX ตรงที่มีวิธีแก้ปัญหาที่พิสูจน์แล้วสำหรับปัญหาเหล่านี้
โดยคำนึงถึงข้อดีและข้อเสียทุกประการ และเมื่อพิจารณาจากประสบการณ์ส่วนตัวของฉัน ฉันแนะนำ Redux เป็นตัวเลือกที่ดีที่สุดสำหรับแอปพลิเคชัน React ระดับองค์กร
