ריאקט Middleware: חיבור בין ממשקי תכנות לרכיבים

Middleware איננו מושג חדש בפיתוח אינטרנט. כלל מותג בדרך כלל עם פריימוורקים של צד שרת כמו Express.js, שם יש הרבה אימות, לוגינג וכו'. עקב יתרונותיו הנטיים, Middleware הרווח תאוצה משמעותית בצד הלקוח.

פריימוורקים לצד הלקוח כמו React מאמצים אותו כדי לטפל בפונקציות מורכבות בזמן ניהול מצב. במדריך זה, נלמד אתכם את המושג של Middleware ב־React וכיצד להשתמש בו על מנת לשפר את פונקציונאליות האפליקציה שלכם ב־React ולנהל את זרימת היישום בצורה יעילה.

עד סופו, תהיו מבינים טוב איך Middleware ב־React פועל וכיצד ליישם אותו עם Redux Thunk.

Middleware ב־React: מפשט את הלוגיקה של היישום

מה זה Middleware?

כפי ששמו מרמז, Middleware הוא שכבה שיושבת בין רכיבים שונים של אפליקציה. זה מספק שכבת עיבוד ופונקציונליות כאן כשלא היה תהליך כזה בלעדיו. Middleware פועל על ידי יידוש בקשות הזורמות מרכיב אחד לאחר ומאפשר לך לבצע פעולות ספציפיות. לאחר הסיום הוא מעביר את הבקשה המשוננת למידלוואר הבא או ליעד המיועד שלה.

זהו עקרון המשמש בעיקר בצד השרת. אך, כפי שצוין מראש, הוא התאים ב־React כדי לשרת מטרה דומה. כעת, נעקוב אחר מהו Middleware במובן ספציפי, ברמת React.

Middleware ב־React

ב־React, middleware מיושם כסדרה של פונקציות, שמבוצעות אחת אחרי השנייה, בסדר שאתה מגדיר. כל פונקציה מקבלת גישה למצב ולפעולות של האפליקציה. לכן, הפונקציות יכולות לשנות ולשחרר פעולות חדשות.

כאשר מצב משתנה ב־React, האפליקציה משחררת פעולות שאז מטופלות על ידי ה־Reducer(s). ה־Reducer(s) אז יחזירו מצב חדש, שאז מאוחסן ומועבר בחזרה לאפליקציה.

Middleware ב־React יושב בין הפעולה שנשחררת ומתפסת אותה לפני שהיא מגיעה ל־reducer. לאחר מכן, זה מאפשר לך להתחבר לתהליך זה ולהריץ קוד מסוים על הפעולה הזו, לדוגמה, לרשום אותה או לבצע שיחת API.

פעם שזה נעשה, זה יעביר את הפעולה ששונתה ל־Reducer (אם אין middleware אחר בשרשרת).

דוגמאות ל־Middleware ב־React

אתה יכול למצוא Middleware ב־React בעיקר ב־Redux, ספריית ניהול מצב מורכבת ל־React. Redux כולל שני סוגי Middleware עיקריים:

  • Thunk – נעמק עמוק יותר באיך להשתמש במידלוואר הזה כדי לשנות פעולה.
  • Saga.

כל אחד מטפל בסוגים שונים של שינויים לפעולות, כפי שנראה למטה כאשר נבחן את השימושים במידלוואר ב־React. ספריות אחרות של React, כמו React Query, גם משתמשות ב־Middleware (יותר על כך מאוחר יותר).

לפני שנסתכל על איך ליישם את זה, בואו נעבור על השימושים השונים במידלוואר ב־React.

שימושים של Middleware ב־React

React middleware מועיל למטרות השימוש הבאות:

ניפוי שגיאות ולוגים

React middleware יכול לשמש לרישום מידע כגון מצב נוכחי, פעולות ונתונים נוספים במהלך פיתוח היישום. יתר על כן, אלה יכולים להיות שימושיים לזיהוי באגים פוטנציאליים ושגיאות לפתרון מוקדם.

ה-Redux Logger (ל-Redux) יכול לעזור לך בכך. הוא מפעיל לוגים על פעולות Redux ושינויים במצב לצורך ניפוי שגיאות קל. הוא מפנה כל פעולה שנשלחת ומספק לוגים על המצב הקודם, הפעולה והמצב הבא.

אימות ואימות זהות

אם ברצונך לאמת משתמשים לפני שאתה מעדכן מצב, ניתן להשתמש ב-Redux Thunk או Saga כדי לטפל בזרימות האימות. לאחר שאתה מפנה פעולה זו, middleware זה מאפשר לך לאחסן טוקנים, לבדוק אימות לפני שהוא מפנה את הפעולה, או לרענן טוקנים.

במילים אחרות, middleware אלה שימושיים לבדיקה האם משתמש מאומת לגישה לנתיב מסוים או לא.

פעולות המבוססות על אירועים

ה-React reducer מיועד להפעלת קוד סינכרוני. זה אומר שאם תנסה להפעיל כל שהוא אסינכרוני עליו, זה לא יעבוד. בעזרת middleware כגון Redux Thunk, ניתן לתפוס את הפעולה, לבצע משימות אסינכרוניות כמו קריאת API, ולהמשיך ל-reducer פעם שזה נעשה.

אחסון נתונים

React Query (middleware נוסף של React) יכול לשמש ככלי יעיל במידע של אפליקציית המטמון. הוא מטמן תגובות API באופן אוטומטי ומבצע חידוש שלהן כאשר נדרש. כתוצאה מכך, הוא עוזר לך למנוע שיחות API מיותרות על ידי בדיקה של המידע הנדרש במטמון.

שיפור ביצועים

מידע של React יכול גם לעזור לשפר את ביצועי האפליקציה על ידי השהיית פעולות בלתי נחוצות למועד מאוחר יותר, השהיית אירועים ועיבוד מטופל של משימות מסוימות. על ידי מטילת תגובות API, React Query גם משפר את ביצועי האפליקציות שלך ב-React.

איך להשתמש ב-Middleware ב-React?

Redux הוא כלי עוצמתי לניהול מצב גלובלי באפליקציות React. זה כולל מספר middleware בתיקיית הכלים שלו שניתן להשתמש בהם כדי להוסיף פונקציונליות מותאמת אישית לאפליקציות ה-React שלך. אחד הנפוצים ביותר הוא Redux Thunk.

מבוא ל-Redux Thunk

לפני שנתפקד עמוק ביותר למימוש של Thunk, בואו נאסוף מידע מסוים עליו כך שנוכל להשתמש בו ביעילות.

מהו Thunk?

בתכנות כללי, "Thunk" הוא פשוט פונקציה שמשמשת להשהות את הערך ואת ביצוע הפונקציה. אנו יכולים לראות אותו כפונקציה שמדחה פעולה עד שתנדרש תנאי מסוים.

ב-Redux, Thunk הוא פונקציה ספציפית המשמשת עם middleware של Redux Thunk. Redux Thunk מיועד לאפשר פעולות אסינכרוניות באפליקציה שלך ב-React. כמו שציינו בעבר, ה-Reducer בנוי להריץ קוד סינכרוני. זה אומר שכאשר נשלחת פעולה, ה-Reducer מעדכן את המצב מיידית.

רדוקס Thunk כ Middleware

רדוקס Thunk פועל כ middleware. זה מאפשר לך לכתוב action creators שמחזירים פונקציות (thunks) במקום אובייקטי פעולה פשוטים. פונקציות אלו יכולות להכיל לוגיקה אסינכרונית. כאשר אתה מפעיל thunk, middleware ה-Thunk מפנה אותו ומבצע את הפונקציה.

בתוך ה־thunk, אתה יכול לבצע את הפעולה האסינכרונית שלך (למשל, לבצע קריאה ל-API) ולאחר מכן לשדר פעולות רגילות כדי לעדכן את חניית ה־Redux כאשר הפעולה הושלמה.

הערה: רדוקס Thunk מאפשר פעולות אסינכרוניות וסינכרוניות, אף על פי שמטרתו העיקרית היא לסייע בפעולות אסינכרוניות. זה לא מונע ממך לשדר פעולות סינכרוניות; הוא פשוט מספק מנגנון לטיפול בפעולות אסינכרוניות גם.

עם זה מאוחזת, בואו נראה את middleware של React בפעולה על ידי הטמעת Redux Thunk.

מדריך שלב אחרי שלב להטמעת Redux Thunk

הטמעת middleware של Redux כוללת את השלבים הבאים:

שלב 1: הגדר את Uפ Redux עם Thunk

צור אפליקציית React והתקן את התלותי הבאות.

Plain Text

 

npx create-react-app newApp

שלב 2: התקן את Redux Thunk

הרץ את הפקודה הבאה כדי להתקין Redux Thunk.

Plain Text

 

npm install redux-thunk

שלב 3: אפשר Middleware של Thunk

JavaScript

 

Enable the Thunk middleware in the Redux store.

import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
import rootReducer from './reducers'; // Combine all reducers here

const store = configureStore({
reducer: rootReducer,
middleware: [thunk],
});

export default store;

הערה: כאשר משתמשים ב־Redux Toolkit, אין צורך להתקין את thunk באופן פשוט.

שלב 4: כתיבת פונקציה אסינכרונית

פונקציית Thunk מחזירה פונקציה נוספת שמקבלת את הארגומנטים dispatch ו־getstate כדי לקרוא את המצב או לשלוח פעולות. הנה קוד הדוגמה לקבלת נתונים:

JavaScript

 

// סוגי פעולות
const START_FETCH = 'START_FETCH';
const FETCH_SUCCESS = 'FETCH_SUCCESS';
const FETCH_ERROR = 'FETCH_ERROR';

  // יוצרי פעולות
const startFetch = () => ({ type: START_FETCH });
const fetchSuccess = (data) => ({ type: FETCH_SUCCESS, payload: data });
const fetchError = (error) => ({ type: FETCH_ERROR, payload: error });

  // פעולת Thunk
export const fetchData = () => {
return async (dispatch, getState) => {
      dispatch(startFetch()); // Notify that the fetch has started

try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const data = await response.json();

        dispatch(fetchSuccess(data)); // Send the fetched data to the store
} catch (error) {
         dispatch(fetchError(error.message)); // Handle any errors
}
};
  };

שלב 5: טיפול בפעולות שנשלחו ב־Reducer

טפלו בפעולות שנשלחו על ידי עדכון ה־reducer.

JavaScript

 

const initialState = {
data: [],
    isLoading: false,
    error: null,
};

export const dataReducer = (state = initialState, action) => {
switch (action.type) {
case START_FETCH:
return { ...state, isLoading: true, error: null };
case FETCH_SUCCESS:
return { ...state, isLoading: false, data: action.payload };
case FETCH_ERROR:
return { ...state, isLoading: false, error: action.payload };
default:
return state;
}
  };

שלב 6: שליחת Thunk מרכיב

השתמשו ב־hook useDispatch כדי לשלוח thunks בפרוייקטים של React.

JavaScript

 

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchData } from './actions';

const DataComponent = () => {
const dispatch = useDispatch();
const { data, isLoading, error } = useSelector((state) => state.data);

useEffect(() => {
      dispatch(fetchData()); // Trigger the thunk to fetch data
}, [dispatch]);

if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;

return (
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
};

export default DataComponent;

שימוש ב־createAsyncThunk

ה־Redux Toolkit מכיל API מובנה שמגדיר לוגיקה ברמה גבוהה לפונקציות אסינכרוניות, שולח פעולות אליהן ומטפל בשגיאות מיד. יש לשים לב שמאחר שזה מספק הסתרה עבור מקרים המסוימים של פונקציות אסינכרוניות, createAsyncThunk לא נחוץ לכל מקרה השימוש ב־thunks.

הנה קוד המימוש הדוגמתי של createAsyncThunk:

JavaScript

 

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

export const dataFetch = createAsyncThunk('data/fetchData', async () => {
const response = await fetch('https://api.example.com/data');
return response.json();
});

const dataSlice = createSlice({
    name: 'data',
    initial_State: { data: [], loading: false, error: null },
extraReducers: (builder) => {
builder
.addCase(dataFetch.pending, (state) => {
          state.loading = true;
          state.error = null;
})
.addCase(dataFetch.fulfilled, (state, action) => {
          state.loading = false;
state.data = action.payload;
})
.addCase(dataFetch.rejected, (state, action) => {
          state.loading = false;
state.error = action.error.message;
});
},
});

export default dataSlice.reducer;

עכשיו, כדי לשלוח את ה־thunk dataFetch, השתמשו בקוד הבא:

JavaScript

 

dispatch(dataFetch ());

שימושים של Middleware של React – Redux Thunk

Thunks ניתן להשתמש בהם למגוון מטרות, כולל אך לא מוגבל ל:

  • הסתרת לוגיקה מורכבת מהרכיבים.
  • ביצוע בקשות אסינכרוניות ולוגיקה.
  • כתיבת פונקציות לשליחת מספר פעולות בסדר.

React Middleware in Other State Management Libraries

Redux לא היא הספרייה היחידה ב-React שמשתמשת ב- middleware. בנוסף, תוכל למצוא אותם גם בספריות ניהול מצב אחרות, אם כי המימוש של המושג הזה בספריות אלה שונה מאופן המימוש של Redux.

MobX

MobX אין לו middleware מסורתי כמו Redux. הוא מציע פונקציונליות דומה דרך מנגנונים כגון interceptors, observers, ו-reactions. מנגנונים אלו מאפשרים לך לצפות בשינויים במצב ה-MobX שלך ולהגיב אליהם. בצורה זו, MobX מספק דרכים לטיפול באפקטים צדדיים, לוגינג, ומשימות אחרות שממושג middleware טיפל בדרך כלל ב-Redux.

Recoil

Recoil אינו תומך ב- middleware באותה דרך כמו Redux מכיוון שאין לו צורך בכך. הוא מאפשר לך לעדכן ישויות במצב (אטומים) ישירות באמצעות פונקציות ספציפיות. אין פעולת מעבירה של פעולות למטפל, אותן תוכל להפריע עם middleware. כדי לטפל בפעולות אסינכרוניות, הוא משתמש ב-selectors – מצב מובן על פי אטומים או selectors אחרים.

Zustand

זה עוזר לנהל מצבים ב-API פשוט ותומך ב- middleware טבעי ללוגינג ולאחסון מצבים, בדיוק כמו Redux.

XState

XState תומך בהתנהגות דומה ל- middleware באמצעות hooks כמו onTransition, actions, ומשרות. חוקים אלו מסייעים להפריע ולשנות את המעברים במצב.

Conclusion

Middleware פועל כגשר לחיבור ושילוב של רכיבים שונים באפליקצית האינטרנט לזרימת נתונים וטיפול טוב יותר. הם נמצאים בשימוש רחב בצד השרת מאז זמן רב, אך כעת נמצאים בשימוש גם בצד הלקוח.

ב-React, קיימים דרכים שונות ליישום של middleware. הם נמצאים בדרך כלל מקושרים לספריות ניהול המצב כגון Redux ו-MobX. ה-middleware של React הנפוץ ביותר, Thunk, כלול בספריית Redux. Thunk הוא קטע קוד שמבצע משימות מאוחרות.

במאמר זה, חקרנו Middleware ב-React, ספריית Redux, ו-Redux Thunk. גילינו גם את השלבים ליישום middleware של Redux Thunk לקבלת נתונים ושיחרוז פעולות.

Source:
https://dzone.com/articles/demystifying-react-middleware-bridging-apis-and-co