React Redux For Beginners

React Redux For Beginners

·

5 min read

In this article, I’ll give you a quick overview of Redux, especially how to use it with React.

Redux helps us manage state and makes it accessible globally. This is really useful in bigger applications, because relying only on component or context state can get messy and hard to keep track of.

Also, this post is meant for beginners, so I’ll keep things simple and not go too deep into technical details.

Slice

A slice contains the “information” of the state—meaning its initial state and all the functions needed to update it. Let’s take this modal state as an example:

const [modal, setModal] = useState(null)

function showModal(object) {
    setModal(object)
}

function closeModal() {
    setModal(null)
}

This is a simple state setup for a modal component. You can toggle it by calling the showModal or closeModal function. Normally, you’d store this state inside a component or maybe in a context file, if multiple components need access to it.

In Redux, especially when using Redux Toolkit, you could set up the same modal state like this:

import { createSlice } from "@reduxjs/toolkit"

const modalSlice = createSlice({
    name: "modal",
    initialState: {value: null},
    reducers: {
        showModal: (state, action) => {
            state.value = action.payload
        },
        closeModal: (state) => {
            state.value = null
        },
    }
})

export default modalSlice.reducer

All the state’s info is inside an object, which we pass into the createSlice function. This function automatically generates a slice that includes the initial state and the functions (reducers) to update it. With that, we now have access to the reducer property, which we need to export so it can be added to our Redux store.

Store

The store holds all the different slices inside a rootReducer. We can set this up in a separate file like this:

import { configureStore } from "@reduxjs/toolkit"
import modalReducer from "../Slices/modalSlice"

export const store = configureStore({
  reducer: {
    modal: modalReducer,
  },
});

We create our store using the configureStore function, which takes an object with a reducer property. This reducer object contains all our slices, where the key is the slice’s name (in this case, "modal"), and the value is its corresponding reducer.

Now, to make our modal reducer accessible from anywhere in our React app, we need to wrap our App component with a Provider—just like we would with a Context file—and pass the store as a prop:

import { Provider } from "react-redux"
import { store } from "./redux/store.js"

ReactDOM.createRoot(document.getElementById("root")).render(
  <Provider store={store}>
    <App />
  </Provider>
)

With this, we’ve now connected our store to the entire application, meaning any component can access the Redux state when needed.

Reducers and Actions

Reducers are functions that let you update the state inside your slice. They work similarly to setter functions in a useState hook, allowing you to modify the state. Here’s how it looks like:

import { createSlice } from "@reduxjs/toolkit"

const modalSlice = createSlice({
    name: "modal",
    initialState: {value: null},
    reducers: {
        showModal: (state, action) => {
            state.value = action.payload
        },
        closeModal: (state) => {
            state.value = null
        },
    }
})

export const { showModal, closeModal } = modalSlice.actions
export default modalSlice.reducer

Each function inside the reducers object has access to the slice’s state and an action object. The action object contains a payload, which holds the value passed into the reducer function. Every function inside our reducers object automatically gets added to the actions object of the slice. That’s why we can export them and use them directly in our components.

To call a reducer function inside a component, we need to import the useDispatch hook and the action we want to trigger:

import React from "react"
import { useDispatch } from "react-redux"
import { showModal } from "../Slices/modalSlice"

const Button = () => {
  const dispatch = useDispatch()

  return (
    <button onClick={() => dispatch(showModal("some payload"))}>Open Modal</button>
  )
}

export default Button

Here, we use useDispatch to get access to the dispatch function, which we then call inside the onClick event. When the button is clicked, it dispatches the showModal action with "some payload" as its argument, updating the Redux state.

The showModal("some payload") call is our action creator. Action creators are functions that return an action object, which looks like this:

{ type: "modal/showModal", payload: "some payload" }

When you call dispatch inside your component, you’re not directly invoking the reducer function. Instead, you’re sending an action object to the Redux store. This object is created by the action creator and contains:

  • A type property → Identifies the action.

  • An optional payload → Holds the data being passed to the reducer.

The root reducer, which manages the store, looks at the type to figure out where the action should be processed. It does this by checking the prefix of the type, which matches the slice name (e.g., "modal"). Based on this, Redux automatically routes the action to the correct slice and executes the reducer function associated with the action name (showModal).

To consume the modal state inside a component, we use the useSelector hook:

import React from "react"
import Modal from "./Components/Modal"
import { useSelector } from "react-redux"

const App = () => {
  const modal = useSelector((state) => state.modal.value)
  return (
    <div style={{ position: "relative" }}>
      {modal && <Modal modal={modal} />}
    </div>
  )
}
export default App

The useSelector hook lets us access state from the Redux store. It takes an arrow function as an argument, which receives the entire Redux state and returns the specific piece of state we need. In this case, state.modal.value gives us access to the modal state, and we use it to conditionally render the Modal component when modal is not null.

Alright, that’s the end! Of course, there’s a lot more to Redux—like handling asynchronous operations and managing side effects. But for now, this was just a simple overview of how to create, update, and use state with Redux.

Thanks for reading! Hope this helped, and happy coding! 🚀