STOP med at bruge Redux blindt!
Som en doven udvikler — jeg købt det ikke. Jeg havde følelsen af, at at bruge standard state og context var meget bedre. Der var meget for meget boilerplate i Redux, og selvom separation of concerns var valid, kunne det meget nemt opnås ved at bruge et custom hook. Vi brugte også redux-saga til at interagere med backend. Det føltes som endnu en unødvendig byrde for mig.
Men jeg begyndte min karriere — så jeg tænkte, jeg skulle give det en fair chance. Jeg brugte redux og redux-saga i omkring et år. Og mine argumenter imod det blev kun intensiveret. Jeg blev ved med at spørge — hvorfor bruger vi redux, og mine seniorer gav mig svar som —
- Det gør koden mere testbar
- Det adskiller forretningslogikken fra komponentlogikken
- Det anbefales ikke at bruge useState til komplekse datatyper (såsom objekter eller arrays af objekter)
- redux-saga kan give dig mere kontrol over API-tilstanden
- Du kunne bruge context, men hvor mange context-providere vil du omslynge din app med?
På alle disse havde jeg svar, men ikke super-overbevisende. Jeg mener, Redux var Redux — brugt af millioner af udvikler og store virksomheder — og jeg var bare en junior softwareentwickler med frustration over boilerplate.
Nu, efter at have arbejdet som Team Lead, kan jeg med sikkerhed sige, at mine seniorer tog alle fejl — og de ville være enig. Min grund til at skrive denne artikel er, at selv i dag er der så mange virksomheder, der bruger redux og accepterer det som en blind standard. Vi skal stoppe op og se på de alternativer, vi har!
For at starte skal vi forstå det problem, jeg har med redux mere klart. Her er mængden af kode, vi skulle skrive til en simpel count state ved hjælp af redux. Selvfølgelig er dette bare et eksempel — viser ikke en ægte applikation, men det er ret effektivt.
// src/actionConstants.js
const ACTION_CONSTANTS = {
INCREMENT_COUNT: "INCREMENT_COUNT",
DECREMENT_COUNT: "DECREMENT_COUNT",
RESET_COUNT: "RESET_COUNT"
}
// src/store/countStore/reducer.js
const initialState = { count: 0 }
export const countReducer = (state = initialState, action) => {
switch (action.type){
case ACTION_CONSTANTS.INCREMENT_COUNT:
return { count: state.count + 1 };
case ACTION_CONSTANTS.DECREMENT_COUNT:
return { count: state.count - 1 };
case ACTION_CONSTANTS.RESET_COUNT:
return initialState;
}
}
// src/store/countStore/selectors.js
export const useCountReducer = () => {
return useSelector(store => store.countReducer)
}
// src/store/countStore/actions.js
export const incrementCount = () => ({
type: ACTION_CONSTANTS.INCREMENT_COUNT
})
export const decrementCount = () => ({
type: ACTION_CONSTANTS.DECREMENT_COUNT
})
export const resetCount = () => ({
type: ACTION_CONSTANTS.RESET_COUNT
})
// src/store/index.js
const rootReducer = combineReducers({ countReducer: countReducer, ... });
Er det ikke bare kriminelt? Dette tager stadig ikke højde for koden, der går ind i din saga eller thunk, når du interagerer med backend — dette er bare for en regelmæssigt delt state-variabel — count. Forestil dig mængden af besvær, du skal igennem bare for at lave en mindre ændring af logikken — hoppe fra en fil til en anden og sikre at disse ændringer er konsistente på tværs af filer.
Redux er beregnet til at være en global store. Det skal bruges til at dele state på tværs af alle komponenter i din app. Men problemet er, at når virksomheder starter med at bruge redux, har de en tendens til at gemme al deres API-tilstand (som 'måske' skal deles i fremtiden) ved hjælp af redux. Det giver mening for et projekt, hvor mange mennesker skal arbejde — og du ønsker at have en konsistent måde at skrive kode på. Dog øges kodens størrelse og reduceres vedligeholdeligheden drastisk.
Selvom de har introduceret redux-toolkit, og det renser koden lidt op — det sammenligner stadig ikke med mange andre biblioteker derude, der hjælper med jobbet meget bedre. Her er stack-stakken, vi bruger på My Next Developer:
React-Query: Jeg bruger react-query til at administrere alle API-tilstande i mine apps. Det administrerer internt loading, error og success-tilstande for alle API-kald, cachelagrer resultater for at undgå genindlæsning og gør det super nemt at få adgang til dataene på tværs af flere komponenter. Dette er et fantastisk værktøj — når du har brugt det, lover jeg dig, at du ikke kommer tilbage. Simpel dokumentation og en hooks-baseret implementering gør det meget rent. Her er en populær YouTube-afspilningsliste af React Query Tutorial for Beginners af Codevolution for at lære react-query.
Context: Der er meget få tilfælde, hvor vi har en ikke-API-baseret global state, der skal deles på tværs af flere komponenter. I disse få tilfælde er context det nemmeste at implementere. Det tilføjer heller ikke unødvendigt et andet bibliotek til blandingen.
Er du uenig? Jeg ville gerne høre dine tanker!


