kontakta oss

React Native och Redux är den kombination de flesta team väljer när en app växer ur sin lokala komponentstatus. Den här guiden visar hur du kopplar ihop dem, hur du behåller statusen vid omstarter och hur du avgör om mönstret är värt att använda överhuvudtaget. Tänk på det så här: utan en store skickas statusen ner genom komponentträdet som ett paket i en korridor, där varje komponent bara håller i det för att skicka det vidare. Redux ersätter korridoren med ett förråd. Ett rum, en loggbok, och vilken skärm som helst kan läsa det den behöver utan att störa grannarna.
Det finns två sätt att ta sig igenom den här sidan. Om du bygger appen, följ genomgången från början till slut. Om du är teknisk ledare eller grundare och funderar på om ni ska använda Redux, hoppa direkt till testet med fyra frågor om status och FAQ:n. Oavsett vilket är den underliggande frågan lika mycket kommersiell som teknisk: ett förutsägbart statuslager byter lite inledande boilerplate mot snabbare onboarding och lägre risk för problem vid ändringar senare, och testet med fyra frågor hjälper dig att avgöra om det är en bra affär.
Detta är en nybörjarguide till Redux och Redux Toolkit i en React Native-applikation, och den förutsätter att du kan grunderna i React Native. Är du ny på det också? Börja med vår guide till React Native och Expo, eller den officiella dokumentationen för React Native, och kom sedan tillbaka.
Vi använder en Android-emulator genom hela guiden. Den simulerar en Android-enhet på din dator så att du kan testa på olika enheter och Android API-nivåer utan att behöva äga varje telefon fysiskt. Den ger dig nästan allt som en riktig enhet gör. Vår guide till React Native och Expo täcker hur du sätter upp den miljön.
För att göra det konkret bygger vi en enkel räknarapplikation under arbetets gång. Den kommer att se ut ungefär så här:

Här är koden för vår SimpleCounter -komponent:
// components/SimpleCounter.js
import React from 'react';
import { View, Text, Button, TextInput } from 'react-native';
const SimpleCounter = () => (
<View>
<Text>0</Text>
<Button title="-" onPress={() => {}} />
<Button title="+" onPress={() => {}} />
<TextInput keyboardType="numeric" placeholder="Amount" />
<Button title="Change by amount" onPress={() => {}} />
</View>
);
export default SimpleCounter;Just nu är koden statisk. Ingen status har deklarerats inuti komponenten än, och varje exempel som följer bygger vidare på detta. När din miljö är redo, installera redux och react-redux bibliotek:
npm install redux react-reduxEn notering om konfigurationen: installerar vi det friståendereduxpaketet här så att du kan se mekaniken från grunden. För ett helt nytt projekt är paketet du faktiskt bör använda Redux Toolkit,npm install @reduxjs/toolkit react-redux, vilket är Redux-teamets rekommenderade standard. Vi bygger upp till det senare i den här guiden, så att du förstår vad det gör åt dig.
Redux är ett JavaScript-bibliotek för att hantera tillståndet i din applikation. Det ger dig en central plats som kallas för store, där tillståndet sparas och ändras genom actions och reducers. Det är med andra ord ett lager, komplett med en loggbok som håller koll på vem som ändrat vad.
Denna centrala plats gör att du kan dela tillstånd mellan olika skärmar och ha full kontroll över var och hur det ändras. Det är ett ovärderligt verktyg i växande applikationer – sådana som blivit för komplexa för att överblicka, vilket ofta är just det som leder till buggar.
Redux hanterar applikationstillstånd genom en kombination av actions, reducers och store. Lär dig hur dessa tre abstraktioner hänger ihop, så är resten bara detaljer.

Applikationstillstånd är all information som din app använder eller ändrar. Centralisera den och ge den ett förutsägbart sätt att förändras, så slutar dina vyer att visa motstridig information.
Detta är extra viktigt i stora enkelsidiga applikationer (SPA), det vill säga appar som laddas en gång och sedan uppdaterar skärmen på plats istället för att hämta en ny sida för varje interaktion.
Actions och reducers ändrar tillståndet tillsammans. Actions avgör vad som ändras och var. Reducers anger hur. Om vi tittar på räknaren från början av det här inlägget behöver vi tre actions: INCREMENT, DECREMENT, och CHANGE_BY_AMOUNT.
Actions är objekt med ett type -attribut och ett payload -attribut. Typen är actionens identifierare, och payloaden bär med sig allt som reducern behöver för att kunna ändra tillståndet. Våra två första actions ändrar bara räknaren med 1, så de behöver bara en typ och inget mer. Den tredje behöver en payload för att ange med hur mycket.
Deklarera dina actions i en separat fil som heter Actions:
// redux/Actions.js
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const CHANGE_BY_AMOUNT = 'CHANGE_BY_AMOUNT';
export const increment = () => ({ type: INCREMENT });
export const decrement = () => ({ type: DECREMENT });
export const changeByAmount = (amount) => ({
type: CHANGE_BY_AMOUNT,
payload: { amount },
});Namnge åtgärder efter vad som har hänt, inte efter den hanterare du vill köra. I våra projekt överlever åtgärdsnamn som läses som händelser refaktoreringar. Namn som läses som funktionsanrop döps om första gången två skärmar behöver samma ändring. Redux style guide argumenterar för samma sak om du vill ha hela resonemanget.
Härnäst, det initiala tillståndet. Det ligger i en separat fil tillsammans med reduceraren:
// redux/Reducer.js
import { INCREMENT, DECREMENT, CHANGE_BY_AMOUNT } from './Actions';
const initialState = {
counter: { amount: 0 },
};Det initiala tillståndet innehåller ett objekt som heter counter med en amount -attribut, som börjar på 0. Du märker säkert att det är en konstant snarare än en variabel, vilket kan verka märkligt för något som beskrivs som tillstånd. Vi återkommer till varför.
Nu till reduceraren, en funktion som tar det nuvarande tillståndet och åtgärden som argument och skapar det nya tillståndet:
// redux/Reducer.js (continued)
const counterReducer = (state = initialState, action) => {
switch (action.type) {
case INCREMENT:
return { ...state, counter: { amount: state.counter.amount + 1 } };
case DECREMENT:
return { ...state, counter: { amount: state.counter.amount - 1 } };
case CHANGE_BY_AMOUNT:
return {
...state,
counter: { amount: state.counter.amount + action.payload.amount },
};
default:
return state;
}
};
export default counterReducer;Vi får aldrig mutera tillståndet inuti en reducerare. Varför inte? Därför att reduceraren inte ska ändra tillståndsobjektet direkt; den ska returnera ett nytt objekt som blir det nya tillståndet. Reacts renderingsmotor jämför det tidigare tillståndsobjektet med det senaste för att avgöra vad som ska ritas om.
Ändra tillståndet direkt och React ser ingen förändring, vilket gör att den har en felaktig bild av hur din app ser ut för tillfället. Redux-dokumentationen om mönster för oföränderliga uppdateringar förklarar mekaniken i detalj.
Det är därför vi deklarerade det initiala tillståndet som en konstant tidigare. Det är det enda objektet i lagret som ingen får skriva på.
Härnäst kommer själva store-objektet, där tillståndet sparas. Det är praxis att skapa och exportera det från en egen fil:
// redux/Store.js
import { createStore } from 'redux';
import counterReducer from './Reducer';
const store = createStore(counterReducer);
export default store;Observera:createStoreär officiellt föråldrad från och med Redux 5.0.0, så i din kodredigerare kommer den att visas med genomstrykning. Den fungerar fortfarande och kommer att fortsätta göra det, så det går bra att använda den för att lära sig grunderna här, men Redux-teamet avråder från att använda den, eller det friståendereduxpaketet, direkt i ny kod. Dess moderna ersättare är Redux ToolkitsconfigureStore, som vi går vidare till senare i den här guiden. Om du ser en varning om att funktionen är föråldrad i det här steget är det förväntat.
Vi skapar store-objektet med Redux createStore() -metod och skickar med reducer-funktionen som vi definierade tidigare. När store-objektet är på plats kan vi anropa actions via dispatch-metoden, vilket visas senare i guiden, för att ändra tillståndet.
Nu gör vi store-objektet tillgängligt genom att skicka det till Provider -komponenten som omsluter SimpleCounter. Provider skickar vidare store-objektet till den komponenten och allt som finns inuti den.
Provider kommer från react-redux, det officiella biblioteket för att koppla samman React och React Native med Redux. Så här ser det ut:
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './redux/Store';
import SimpleCounter from './components/SimpleCounter';
const App = () => (
<Provider store={store}>
<SimpleCounter />
</Provider>
);
export default App;Nu kopplar vi våra komponenter till storen. I moderna React Native-kodbaser gör du det med två hooks från react-redux: useSelector läser en del av tillståndet, och useDispatch returnerar dispatch-metoden så att komponenten kan skicka tillbaka actions.
// components/SimpleCounter.js
import React, { useState } from 'react';
import { View, Text, Button, TextInput } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, changeByAmount } from '../redux/Actions';
const SimpleCounter = () => {
const amount = useSelector((state) => state.counter.amount);
const dispatch = useDispatch();
const [inputValue, setInputValue] = useState('0');
return (
<View>
<Text>{amount}</Text>
<Button title="-" onPress={() => dispatch(decrement())} />
<Button title="+" onPress={() => dispatch(increment())} />
<TextInput
keyboardType="numeric"
value={inputValue}
onChangeText={setInputValue}
/>
<Button
title="Change by amount"
onPress={() => dispatch(changeByAmount(Number(inputValue)))}
/>
</View>
);
};
export default SimpleCounter;Vi har bara tillgång till state-objektet inuti useSelector eftersom SimpleCounter ligger inbäddad i Provider. Selectorn tar emot hela tillståndet och returnerar endast det värde komponenten behöver, vilket gör att komponenten renderas om när state.counter.amount ändras, men förblir oförändrad när andra, orelaterade delar av storen uppdateras.
Håll dina selectors specifika av den anledningen. Det vanligaste prestandaklagomålet vi hör om Redux i React Native är listor som renderas om vid varje tangenttryckning, och det beror nästan alltid på en selector som returnerar en hel del av tillståndet, eller ett nyskapat objekt, när ett enskilt värde hade räckt.
Äldre kodbaser kopplar samman komponenter med connect -metoden och en mapStateToProps -funktion istället. Den slår samman objektet som returneras från mapStateToProps med komponentens props, så att samma värde nås via this.props.amount:
// legacy pattern, still valid in existing codebases
const mapStateToProps = (state) => ({ amount: state.counter.amount });
export default connect(mapStateToProps)(SimpleCounter);Båda tillvägagångssätten kommunicerar med samma store. Hooks är det rekommenderade mönstret för ny kod och det vi använder i resten av den här guiden. Lär dig connect ändå, eftersom du kommer att stöta på det i alla React Native-projekt som skrevs innan hooks introducerades.
Vi har alltså en centraliserad lagring som sparar och ändrar tillstånd på ett förutsägbart sätt genom actions och reducers. Du kanske har märkt att något saknas. Stäng appen, öppna den igen, och räknaren är tillbaka på noll.
Det beror på att ingenting sparar tillståndet permanent. Varje gång applikationen startar återställer reducern räknaren till dess ursprungliga värde.
Persistens är viktigt när information måste finnas kvar efter att sessionen avslutats: inloggningstokens, konfigurationsinställningar eller ett utkast som användaren höll på att skriva. I React Native löser du detta med biblioteket redux-persist .
Redux Persist skriver ner lagringen till en lokal persistent lagringsenhet och läser in den igen varje gång appen öppnas eller uppdateras. Vi använder en Android-emulator här, men det fungerar precis lika bra på iOS. Börja med att installera det, tillsammans med AsyncStorage, nyckel-värde-lagringen som det skriver till:
npm install redux-persist @react-native-async-storage/async-storageÄndra sedan filen Store.js enligt följande:
// redux/Store.js
import { createStore } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import counterReducer from './Reducer';
const persistConfig = {
key: 'root',
storage: AsyncStorage,
};
const persistedReducer = persistReducer(persistConfig, counterReducer);
export const store = createStore(persistedReducer);
export const persistor = persistStore(store);Importera persistStore och persistReducer från redux-persist. Skicka din reducer till persistReducer tillsammans med persistConfig -objektet, så får du en persistedReducer tillbaka.
I persistConfig anger du att AsyncStorage ska lagra tillståndet. AsyncStorage är React Natives nyckel-värde-lagring och den är okrypterad, så allt känsligt material, och i synnerhet autentiseringstokens, bör istället placeras i säker lagring.

Slutligen anropar du persistStore för att behålla tillståndet persistent. I större projekt kanske du inte vill att hela tillståndet skrivs till disk, och det är vad alternativen whitelist och blacklist i persistConfig är till för: välj de reducers som är värda att spara och lämna resten. I redux-persist README dokumenteras båda.
Sist, i App.js, importerar du persistor från Store.js och omslut SimpleCounter med PersistGate. Den håller tillbaka gränssnittet tills det lagrade tillståndet har hämtats och lästs in i storen, så att användare aldrig ser det initiala tillståndet blinka till innan det riktiga visas:
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './redux/Store';
import SimpleCounter from './components/SimpleCounter';
const App = () => (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<SimpleCounter />
</PersistGate>
</Provider>
);
export default App;Redux Toolkit är ett bibliotek skrivet av utvecklarna bakom Redux för att hjälpa dig skapa mer effektiv Redux-logik. Det är vad Redux-teamet rekommenderar för nya projekt, och det ersätter det mesta av koden ovan med en bråkdel av den.
Det är också här ekosystemet har landat: Redux Toolkit är Redux-teamets officiella rekommendation för alla nya projekt, och den stora majoriteten av React-Redux-installationer använder det numera istället för att skriva Redux-kod för hand. Vi använder det även i produktion. TrustPortal körs på Redux Toolkit för att hålla tillståndet förutsägbart i en stor företagsapplikation, vilket är precis den vinst som beskrivs här. Nedan följer en genomgång av de viktigaste funktionerna.
createAction() för att deklarera actionsRedux Toolkit ger oss ett nytt sätt att skapa en action:
import { createAction } from '@reduxjs/toolkit';
export const increment = createAction('INCREMENT');
export const decrement = createAction('DECREMENT');
export const changeByAmount = createAction('CHANGE_BY_AMOUNT');createAction tar action-typen som ett argument och returnerar en action creator-funktion. Anropa den funktionen, skicka med payloaden, så får du action-objektet. Du kan också läsa ut typen med metoden toString() , som i increment.toString(). Inga fler deklarationer av action-typer som konstanter, vilket minskar mängden boilerplate avsevärt.
createReducer() för att skriva reducerscreateReducer förenklar den andra halvan. Istället för en switch-sats mappar du varje action till funktionen som hanterar den, vilket är betydligt mer lättläst, och action creators som returneras av createAction() kan skickas direkt till addCase(). Med samma reducer-logik som tidigare:
import { createReducer } from '@reduxjs/toolkit';
import { increment, decrement, changeByAmount } from './Actions';
const initialState = { counter: { amount: 0 } };
const counterReducer = createReducer(initialState, (builder) => {
builder
.addCase(increment, (state) => ({
...state,
counter: { amount: state.counter.amount + 1 },
}))
.addCase(decrement, (state) => ({
...state,
counter: { amount: state.counter.amount - 1 },
}))
.addCase(changeByAmount, (state, action) => ({
...state,
counter: { amount: state.counter.amount + action.payload },
}));
});createReducer() använder också Immer, ett bibliotek som låter dig skriva kod som ser ut att mutera tillståndet, medan det i bakgrunden skapar en ny kopia. Immer översätter varje muterande operation till motsvarande kopieringsoperation. Det betyder att vi kan skriva vår reducer så här:
const counterReducer = createReducer(initialState, (builder) => {
builder
.addCase(increment, (state) => {
state.counter.amount += 1;
})
.addCase(decrement, (state) => {
state.counter.amount -= 1;
})
.addCase(changeByAmount, (state, action) => {
state.counter.amount += action.payload;
});
});Betydligt kortare. Samma beteende.
createSlice() för både actions och reducersI praktiken anropar du sällan createAction och createReducer var för sig. createSlice genererar båda utifrån en enda definition: namnge din slice, ange ett initialt tillstånd och en uppsättning reducer-funktioner, så får du tillbaka både reducern och en matchande action creator för varje funktion.
// redux/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { amount: 0 },
reducers: {
increment: (state) => {
state.amount += 1;
},
decrement: (state) => {
state.amount -= 1;
},
changeByAmount: (state, action) => {
state.amount += action.payload;
},
},
});
export const { increment, decrement, changeByAmount } = counterSlice.actions;
export default counterSlice.reducer;Hela Actions.js och Reducer.js paret från tidigare slås samman till den filen. Dina komponenter fortsätter att använda useSelector och useDispatch precis som tidigare.
configureStore() för att skapa storeconfigureStore() omsluter createStore() och konfigurerar förnuftiga standardinställningar, inklusive anslutning till Redux DevTools och standard-middleware, vilket innebär de funktioner som varje action passerar genom på väg till reducern. Eftersom det är den moderna efterföljaren till den numera utfasade createStore, är det vad du bör använda i alla nya projekt.
Den tar även ett konfigurationsobjekt istället för en grupp funktioner, så reducern placeras inuti ett objekt under attributet reducer :
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
export const store = configureStore({
reducer: { counter: counterReducer },
});Använd redux-persist och Redux Toolkit i samma projekt och förr eller senare kommer du att stöta på felet 'A non-serializable value was detected in an action'. Orsaken: configureStore() kör en serialiseringskontroll, ett skydd under utvecklingstiden som varnar när en åtgärd innehåller något som Redux inte kan lagra på ett säkert sätt, till exempel en funktion eller ett Promise, och redux-persist behöver skicka funktioner i sina egna åtgärder.
Lösningen är att behålla kontrollen aktiverad men undanta redux-persists åtgärdstyper från den:
import { configureStore } from '@reduxjs/toolkit';
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import counterReducer from './counterSlice';
const persistConfig = { key: 'root', storage: AsyncStorage };
const persistedReducer = persistReducer(persistConfig, counterReducer);
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
});
export const persistor = persistStore(store);Notera skillnaden mellan att undanta dessa sex åtgärdstyper och att stänga av kontrollen helt. Om du stänger av den helt förlorar du varningen för alla värden som faktiskt inte går att serialisera och som din egen kod lägger in i storen. Diskussionen och lösningen finns i redux-persist-ärendet om serialiseringskontrollen.
createAsyncThunk och RTK QueryVår räknare är synkron. Nästan inga riktiga appar är det. Enligt vår erfarenhet är datahämtning den vanligaste anledningen till att ett React Native-team överhuvudtaget börjar använda Redux: en förfrågan har ett laddningstillstånd, ett lyckat tillstånd och ett feltillstånd, flera skärmar behöver alla tre, och att skicka runt dem som props slutar snabbt att fungera.
Redux Toolkit erbjuder två svar, och att välja mellan dem är det praktiska beslut som de flesta team står inför.
createAsyncThunk omsluter ett promise och skickar tre actions åt dig, en per fas, som du hanterar i extraReducers:
// redux/counterSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const fetchCounter = createAsyncThunk(
'counter/fetch',
async (userId) => {
const response = await fetch(`https://api.example.com/counter/${userId}`);
return response.json();
},
);
const counterSlice = createSlice({
name: 'counter',
initialState: { amount: 0, status: 'idle', error: null },
reducers: {
increment: (state) => {
state.amount += 1;
},
},
extraReducers: (builder) => {
builder
.addCase(fetchCounter.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchCounter.fulfilled, (state, action) => {
state.status = 'succeeded';
state.amount = action.payload.amount;
})
.addCase(fetchCounter.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
},
});Komponenten skickar thunken och läser av statusen:
const dispatch = useDispatch();
const { amount, status } = useSelector((state) => state.counter);
useEffect(() => {
if (status === 'idle') dispatch(fetchCounter(userId));
}, [status, dispatch, userId]);RTK Query går ett steg längre. Deklarera dina endpoints så genererar det thunks, reducers, cachen och en hook per endpoint, så att all hantering av laddning och fel försvinner in i hooken:
// redux/api.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: 'https://api.example.com/' }),
endpoints: (builder) => ({
getCounter: builder.query({ query: (userId) => `counter/${userId}` }),
}),
});
export const { useGetCounterQuery } = api;
const { data, isLoading, error } = useGetCounterQuery(userId);Så vilken ska man välja? Använd createAsyncThunk när det asynkrona arbetet är en sidoeffekt du själv kontrollerar, som en inloggningssekvens eller en bakgrundssynkronisering. Använd RTK Query när du cachar serverdata, vilket på mobila enheter är det vanligaste fallet, eftersom cachning, omhämtning och ogiltigförklaring är precis de delar som team ofta gör fel när de bygger dem manuellt. Mark Erikson, en av underhållarna av Redux, förklarar varför thunks är standardverktyget för asynkron logik i denna genomgång av RTK och asynkron logik.
Vår guide om hur man hanterar asynkrona operationer med Redux fördjupar sig i thunks, sagas och middleware-alternativ. För ett produktionsexempel på samma problem med laddning, cachning och omhämtning, Confinze kombinerar Redux med React Query i en fintech-produkt och nådde en bibehållandegrad på 85 % tack vare den förutsägbarheten.
Redux är inte gratis. Det tillför filer, indirektion och ett mönster som varje utvecklare i teamet måste lära sig. Innan vi inför det i ett projekt kör vi testet med fyra frågor, och svaren brukar avgöra saken:
useState är rätt verktyg.
Två eller fler ja-svar och Redux är värt besväret. Ett eller inget, och Reacts inbyggda tillståndshantering plus Context kommer att tjäna dig bättre till en lägre kostnad.
Vi har provat båda vägarna. Ett internt verktyg med en skärm och en utvecklare stannade på useState och levererades snabbare tack vare det. En leveransapp med offline-utkast, push-uppdateringar och ett roterande team skrevs om till Redux Toolkit, just för att buggar i tillståndshanteringen ständigt dök upp från tre håll samtidigt. På AppTweakvar disciplinerad tillståndshantering i en datatung instrumentpanel en del av att korta laddningstiden med 80 %, vilket är den vinst som det här testet egentligen väger.
Det kommersiella perspektivet gäller i båda fallen. Du väger en liten, fast startkostnad mot kostnaden för framtida förändringar: hur snabbt en ny utvecklare blir produktiv, hur tryggt du kan leverera en funktion som rör delad data, och hur stor del av din budget som går åt till att återskapa fel istället för att bygga nytt. Du kan läsa mer om dessa resultat i våra kundcase.
Inte alltid. Sedan hooks och Context introducerades kan många appar hantera delat tillstånd utan det. Redux har fortfarande sin plats när tillstånd läses och skrivs från flera skärmar, behöver överleva en omstart eller underhålls av ett team snarare än en enskild utvecklare. För en enskild skärm med lokalt tillstånd är useState tillräckligt.
De löser olika problem. Context skickar ett värde nedåt i trädet och renderar om alla konsumenter när det ändras, vilket fungerar bra för teman eller språkinställningar. Redux Toolkit tillför förutsägbara uppdateringar, selektiva omrenderingar via selectors, tidsresor i devtools och en dokumenterad plats för varje tillståndsändring. Välj Context för värden som ändras sällan och Redux Toolkit för tillstånd som ändras ofta eller kommer från flera källor.
Installera redux-persist och AsyncStorage, omslut din reducer med persistReducer och en persistConfig, skapa persistor med persistStore, och omslut sedan din app i PersistGate så att gränssnittet väntar på det sparade tillståndet. Använd alternativen whitelist och blacklist för att bara spara de delar som behöver det, och förvara tokens i säker lagring istället för AsyncStorage, som är okrypterat.
Det kommer från configureStores serialiseringskontroll möter redux-persists egna åtgärder. Skicka med ett middleware-alternativ till configureStore och lägg till FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE och REGISTER till ignoredActions. Inaktivera inte kontrollen helt, då förlorar du varningar för värden i din egen kod som faktiskt inte går att serialisera.
createAsyncThunk eller RTK Query för API-anrop?RTK Query för serverdata som du vill cacha, hämta på nytt och ogiltigförklara, vilket täcker de flesta mobilskärmar. createAsyncThunk för sidoeffekter som du hanterar från början till slut, som ett inloggningsflöde eller ett synkroniseringsjobb. Båda ingår i Redux Toolkit, så valet görs utifrån användningsområde snarare än per projekt.
Ofta, ja. Om appen bara har ett fåtal skärmar, en utvecklare och inget tillstånd som överlever en session, kostar boilerplate-koden mer än den smakar. Gör testet med de fyra frågorna ovan: färre än två ja-svar innebär att du klarar dig bättre med useState och Context.
createStore, eller räcker Redux Toolkit?Redux Toolkit räcker, och det är vad Redux-teamet rekommenderar för nya projekt. Den ursprungliga createStore är numera utfasad. configureStore, createSlice och Immer ersätter de manuella action-konstanterna, switch-case-reducerare och den store-konfiguration som visades tidigare i guiden. Den längre formen är fortfarande värd att läsa en gång, eftersom den visar vad verktygslådan gör åt dig, och det är vad du kommer att stöta på i äldre kodbaser.
Actions beskriver vad som hänt, reducers avgör hur tillståndet ändras och storen sparar resultatet så att alla skärmar kan nå det. Redux Toolkit tar bort det mesta av boilerplate-koden, RTK Query hanterar serverdata, redux-persist bevarar tillståndet vid omstarter, och vårt test med fyra frågor hjälper dig avgöra om det är värt att använda. Eftersom Redux är ramverksoberoende kan allt detta även användas i en React-webbapp.
Väger du för- och nackdelar med tillståndshantering för en mobilprodukt, eller har du tagit över en app där tillståndshanteringen blivit en flaskhals? Vårt team arbetar med detta dagligen. Ta en titt på våra utvecklingstjänster, eller berätta om ditt projekt så ger vi dig ett ärligt svar på om Redux är rätt val för dig.


Datavetenskapsstudent och ImaginaryCloud deltidsarbetare. Ivrig efter att lära sig ny teknik och teknik. Tennis- och pianospelare.

Alexandra Mendes är Senior Growth Specialist på Imaginary Cloud med 3+ års erfarenhet av att skriva om mjukvaruutveckling, AI och digital transformation. Efter att ha avslutat en frontend-utvecklingskurs tog Alexandra upp några praktiska kodningskunskaper och arbetar nu nära med tekniska team. Alexandra brinner för hur ny teknik formar affärer och samhälle och tycker om att förvandla komplexa ämnen till tydligt och användbart innehåll för beslutsfattare.
People who read this post, also found these interesting: