What is Redux and Redux Toolkit
Redux is a state management library that helps manage state in React applications. Redux Toolkit is the official library for managing global state in React apps in a simpler and more structured way than regular Redux.
Redux Key Concepts
- Store: Where the application state is stored.
- Action: An object that describes what you want to do. Usually has a type and payload.
- Reducer: A function that determines how the state is changed based on the action received.
- Dispatch: The method to send the action to the store.
- Selector: The function to retrieve data from the store.
Redux Toolkit (RTK) Simplification
RTK makes Redux setup easy with features like:
- configureStore(): Creates a store with default settings.
- createSlice(): Combines action and reducer in one place.
- createAsyncThunk(): Manages async data like an API call.
Set Up Project
Install react with vite
npm create vite@latest
Install react redux and redux tool kit
npm install @reduxjs/toolkit react-redux
Project Structure
Basic Steps
Setup store
// store.ts
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
Integration to app
// main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import App from './App.tsx';
import './index.css';
import { store } from './state/store.ts';
const root = createRoot(document.getElementById('root')!);
root.render(
<StrictMode>
<Provider store={store}>
<App />
</Provider>
</StrictMode>
);
Create slice
// counterSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface CounterState {
value: number;
}
const initialState: CounterState = {
value: 0,
};
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
Update store.ts
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './slice/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
Use redux in components
// App.tsx
import { useDispatch, useSelector } from 'react-redux';
import { AppDispatch, RootState } from './state/store';
import {
decrement,
increment,
incrementByAmount,
} from './state/slice/counterSlice';
export default function App() {
const count = useSelector((state: RootState) => state.counter.value);
const dispatch: AppDispatch = useDispatch();
return (
<div className="min-h-screen w-full flex items-center justify-center gap-x-4">
<button
onClick={() => dispatch(decrement())}
disabled={count === 0}
className="bg-neutral-800 text-neutral-100 text-base px-2 py-1 rounded-md"
>
Decrement
</button>
<span className="text-neutral-900 text-base border border-neutral-800 rounded-md px-2 py-1">
{count}
</span>
<button
onClick={() => dispatch(increment())}
className="bg-neutral-800 text-neutral-100 text-base px-2 py-1 rounded-md"
>
Increment
</button>
<button
onClick={() => dispatch(incrementByAmount(10))}
className="bg-neutral-800 text-neutral-100 text-base px-2 py-1 rounded-md"
>
Increment by Amount
</button>
</div>
);
}
Implement Redux Persist
Persist in Redux is used to save application state to local storage (localStorage or sessionStorage), so that data is not lost when the user refreshes the page. The Redux Toolkit supports this with the help of the redux-persist
library.
Install redux persist
npm install redux-persist
Update store.ts
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './slice/counterSlice';
import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, counterReducer);
export const store = configureStore({
reducer: {
counter: persistedReducer,
},
});
export const persistor = persistStore(store);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
Update main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App.tsx';
import { Provider } from 'react-redux';
import { persistor, store } from './state/store.ts';
import { PersistGate } from 'redux-persist/integration/react';
const root = createRoot(document.getElementById('root')!);
root.render(
<StrictMode>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
</StrictMode>
);
Final Output
Conclusion
I hope this guide helps you understand how to set up and use Redux Toolkit with TypeScript and implement Redux Persist in your React project. Thank you for following along!
Github repository: https://github.com/rfkyalf/redux-toolkit-learn
If you found this helpful, feel free to check out my portfolio for more exciting projects www.rifkyalfarez.my.id
References:
https://redux.js.org/introduction/getting-started
https://redux-toolkit.js.org/introduction/getting-started
Top comments (0)