What is Redux?
Redux is a state management library for JavaScript applications. It helps you manage the state of your application in a predictable way. Redux is like a librarian for your app—organizing state, making it easy to find, and keeping chaos at bay. It works well with React, making state management fun!
What is state actually? Before answering this question, let’s understand why we use libraries like React, Angular, or Vue over vanilla JavaScript. Yes, they provide a way to create reusable UI components, but they also help us manage the state of our application. State is the data that drives your application. It can be anything from a simple boolean value to a complex object.
React provides a way to manage state using component state. But as your application grows in complexity, managing state in React can become challenging. This is where Redux comes in. Redux provides a way to manage the state of your application in a centralized store. This makes it easier to manage state across your application and keep it in sync.
How Redux Works
Redux works by following three core principles:
-
Single Source of Truth: Redux stores the state of your application in a single object called the store. This makes it easier to manage state across your application and keep it in sync.
-
State is Read-Only: In Redux, the state is read-only. This means that you cannot directly modify the state. Instead, you need to dispatch actions to update the state.
-
Changes are Made with Pure Functions: In Redux, changes to the state are made by pure functions called reducers. Reducers take the current state and an action as input and return a new state.
Core Concepts
Redux has a few core concepts that you need to understand to use it effectively:
- Store: The store is the object that holds the state of your application. You can think of it as a database for your application.
- Actions: Actions are payloads of information that send data from your application to your Redux store. They are the only source of information for the store.
- Reducers: Reducers specify how the application’s state changes in response to actions sent to the store. Remember that actions only describe what happened, but don’t describe how the application’s state changes.
- Dispatch: This is the only way to trigger a state change. Dispatching an action is the process of sending an action to the store.
- Selectors: Selectors are functions that take the Redux store state as an argument and return some data to pass to your components.
- Middleware: Middleware provides a way to interact with actions that have been dispatched to the store before they reach the reducers.
Example
Here’s a simple example of how you can use Redux in a React application:
- Install Redux:
- Define actions:
- Define a reducer:
- Create a store:
- Dispatch actions in your components:
Summary
From this example, we can summarize that:
- Store: Holds the state.
- Actions: Describe changes.
- Reducers: Handle state changes.
- Dispatch: Sends actions.
- Selectors: Extract state.
- Middleware: Extend functionality.
Redux Toolkit (RTK)
While Redux is a powerful library, it can be verbose and require a lot of boilerplate code. To address this, Redux Toolkit (RTK) was introduced. RTK is the official, recommended way to write Redux logic. It provides a set of tools and best practices that help you write Redux code faster and with less boilerplate.
Example with RTK
Here’s how you can rewrite the previous example using RTK:
- Install Redux Toolkit:
-
Define a slice:
A slice is a collection of Redux reducer logic and actions for a single feature of your application.
-
Create a store:
Use
configureStore
to create the Redux store and combine slices if you have multiple.
-
Provide the store to your app:
Use the
Provider
component from react-redux to make the Redux store available to your React components.
-
Dispatch actions in your components:
Use the
useSelector
hook to read state from the Redux store and theuseDispatch
hook to dispatch actions.
Summary
From this example, we can summarize that:
- Redux Toolkit: Official way to write Redux logic.
- Slice: Collection of reducer logic and actions.
- configureStore: Create the Redux store.
- Provider: Make the store available to components.
- useSelector: Read state from the store.
- useDispatch: Dispatch actions.
Persisting State
What happens if the user refreshes the page or closes the browser? The state of your application will be lost. To persist the state, you can use redux-persist
. This library allows you to save the state of your Redux store to localStorage
, sessionStorage
, or any other storage engine.
Example with redux-persist
- Install
redux-persist
:
- Configure the store with
redux-persist
:
- Wrap your app with
PersistGate
:
Summary
From this example, we can summarize that:
- redux-persist: Persist the state of your Redux store.
- persistStore: Persist the store.
- PersistGate: Wrap your app to persist the state.
RTK Query
RTK Query is a powerful data fetching and caching tool built on top of Redux Toolkit. It simplifies the process of fetching data from an API and managing the cache. RTK Query provides a set of hooks that make it easy to fetch data in your React components.
Can we combine RTK Query with redux-persist
? Yes, however, it’s important to understand that RTK Query is designed to manage caching, fetching, and synchronization of server data, and it has its own mechanisms for caching data. Persisting the entire RTK Query cache might not always be necessary or recommended, but you can persist specific parts of your state if needed.
Example with RTK Query
- Set up an API slice:
- Create a store with RTK Query:
- Use RTK Query hooks in your components:
Example Handling Authentication
RTK Query provides a way to handle authentication using hooks and endpoints. You can use the useQuery
and useMutation
hooks to fetch data and send mutations with authentication headers. You can also use the baseQuery
option to add authentication headers to all requests.
- Create API service for authentication:
- Update the protected endpoint:
- Create a slice for authentication:
- Update the store configuration:
- Use the
useLoginMutation
hook in your components:
Summary
From this example, we can summarize that:
- RTK Query: Data fetching and caching tool.
- API Slice: Define endpoints for fetching data.
- Caching: RTK Query has its own caching mechanisms.
- Middleware: Use
api.middleware
in the store configuration. - Whitelist: Specify which reducers you want to persist.