Redux the beginners guide!

Hi everyone! I am here to give a small guide explaining on how to use Redux within to manage state within your react application. There are five key concepts to understand in order to incorporate redux in your react application:

Store
Actions
Reducer…


This content originally appeared on DEV Community and was authored by Gianni Castellano

Hi everyone! I am here to give a small guide explaining on how to use Redux within to manage state within your react application. There are five key concepts to understand in order to incorporate redux in your react application:

  1. Store
  2. Actions
  3. Reducers
  4. Dispatch
  5. Selectors

Store
The purpose of store is to have a central hub where all the state within the app is managed. After creating a Store.jsx file, you need to first import configureStore at the top of the file. Then you need to import the files within your app that are modifying states from the slice files. Lastly, you need to combine the reducers from all the slice files into a single root reducer.

Actions
Within your slice files it is necessary to use actions in order to send data from within your app to the Store file. They are generic Javascript objects that require a type property in order to perform the needed action. In the context of my latest project I used them in order to fetch, delete, create, and post data to my backend server.

Reducers
Reducers work hand in hand with actions. They are functions that take the current state and an action as arguments and return a new state without mutating the original data. They state how the app's state will change due to an action.

Dispatch
Just like reducers, dispatch, is a function that works with reducers to send actions to the store file. The dispatch function is used to trigger the reducer which in turn triggers action in order to update the state.

Selectors
Selectors are used in order to grab the data from the state within files in order to update the data accordingly.

Here is code snippets from my latest project in order to give a visual demonstration on the above information

Store.jsx:

import { configureStore } from "@reduxjs/toolkit"
import clanReducer from './ClanSlice'
import eventReducer from './EventSlice'
import clanFormReducer from './ClanFormSlice'
import eventFormReducer from './EventFormSlice'

const store = configureStore({
    reducer: {
        clan: clanReducer,
        event: eventReducer,
        clanForm: clanFormReducer,
        eventForm: eventFormReducer,
    },
})

export default store

ClanSlice.jsx

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import axios from 'axios'

export const fetchClan = createAsyncThunk('clans/fetchClan', async (id) => { 
  const response = await axios.get(`http://127.0.0.1:5555/clans/${id}`)
  return response.data
})

export const deleteClan = createAsyncThunk('clans/deleteClan', async (id) => {
    await axios.delete(`http://127.0.0.1:5555/clans/${id}`)
    return id
})

export const fetchClans = createAsyncThunk('clans/fetchClans', async () => { 
    const response = await axios.get('http://127.0.0.1:5555/clans')
    return response.data
  })

export const createClan = createAsyncThunk('clans/createClan', async (clanData, { dispatch }) => {
      const response = await axios.post('http://127.0.0.1:5555/clans', clanData)
      dispatch(fetchClans())
      return response.data
    })

const clanSlice = createSlice({
    name: 'clan',
    initialState: {
        clans: [],
        clan: [],
        status: 'idle',
        error: null,
    },
    reducers: {
        resetClan: (state) => {
            state.clan = []
            state.status = 'idle'
            state.error = null
        },
        resetStatus: (state) => {
            state.status = 'loading'
        }
    },
    extraReducers: (builder) => {
        builder
        .addCase(fetchClan.pending, (state) => {
            state.status = 'loading'
        })
        .addCase(fetchClan.fulfilled, (state, action) => {
            state.status = 'succeeded'
            state.clan = action.payload
        })
        .addCase(fetchClan.rejected, (state, action) => {
            state.status = 'failed'
            state.error = action.error.message
        })
        .addCase(fetchClans.pending, (state) => {
            state.status = 'loading'
        })
        .addCase(fetchClans.fulfilled, (state, action) => {
            state.status = 'succeeded'
            state.clans = action.payload
        })
        .addCase(fetchClans.rejected, (state, action) => {
            state.status = 'failed'
            state.error = action.error.message
        })
        .addCase(deleteClan.fulfilled, (state, action) => {
            state.clans = state.clans.filter(clan => clan.id !== action.payload)
        })
        .addCase(createClan.fulfilled, (state, action) => {
            state.status = 'succeeded'
            state.clans.push(action.payload)
        })
    },
    })

export const { resetClan, resetStatus } = clanSlice.actions

export default clanSlice.reducer

ClanSlice.jsx

import React, { useEffect } from "react"
import { useDispatch, useSelector } from "react-redux"
import { fetchClans, resetStatus } from "./ClanSlice"
import { Link } from "react-router-dom"
import './Clans.css'

function Clans() {
    const dispatch = useDispatch()
    const clans = useSelector((state) => state.clan.clans)
    const status = useSelector((state) => state.clan.status)
    const error = useSelector((state) => state.clan.error)

    useEffect(() => {
        dispatch(fetchClans())
    }, [dispatch])

    useEffect(() => {
        return () => {
            dispatch(resetStatus())
        }
    }, [])

    let content

    if (status === 'loading') {
        content = <p>Loading...</p>
    } else if (status === 'succeeded') {
        content = (
            <div className="clans-wrapper">
                {clans.map((clan) => (
                    <div key={clan.id} className="clan-box">
                        <h3>
                            <Link to={`/clans/${clan.id}`}>{clan.name}</Link>
                        </h3>
                        <p>{clan.description}</p>
                        <h4>Members:</h4>
                        <div className="members-container">
                            <ul>
                                {clan.members.map((member) => (
                                    <li key={member.id}>
                                        <span className="username-text">Username:</span>{member.username} <span className="role-text">Role:</span> {member.role}
                                        <ul>
                                            {member.participations.map((participation) => (
                                                <li key={participation.id}>
                                                    <span className="event-text">Event:</span> {participation.event.event}
                                                    <br />
                                                    <span className="status-text">Status:</span> {participation.participation_status}
                                                </li>
                                            ))}
                                        </ul>
                                    </li>
                                ))}
                            </ul>
                        </div>
                        <h4>Events:</h4>
                        <div className="events-container">
                            <ul>
                                {clan.events.map((event) => (
                                    <li key={event.id}>
                                        <Link to={`/events/${event.id}`}>{event.event}</Link> - {event.date} - {event.location} - {event.details}
                                    </li>
                                ))}
                            </ul>
                        </div>
                    </div>
                ))}
            </div>
        )
    } else if (status === 'failed') {
        content = <p>{error}</p>
    }

    return (
        <div className="container">
            <h2>Welcome to the Clans Page</h2>
            {content}
        </div>
    )
}

export default Clans


This content originally appeared on DEV Community and was authored by Gianni Castellano


Print Share Comment Cite Upload Translate Updates
APA

Gianni Castellano | Sciencx (2024-08-22T21:46:28+00:00) Redux the beginners guide!. Retrieved from https://www.scien.cx/2024/08/22/redux-the-beginners-guide/

MLA
" » Redux the beginners guide!." Gianni Castellano | Sciencx - Thursday August 22, 2024, https://www.scien.cx/2024/08/22/redux-the-beginners-guide/
HARVARD
Gianni Castellano | Sciencx Thursday August 22, 2024 » Redux the beginners guide!., viewed ,<https://www.scien.cx/2024/08/22/redux-the-beginners-guide/>
VANCOUVER
Gianni Castellano | Sciencx - » Redux the beginners guide!. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/08/22/redux-the-beginners-guide/
CHICAGO
" » Redux the beginners guide!." Gianni Castellano | Sciencx - Accessed . https://www.scien.cx/2024/08/22/redux-the-beginners-guide/
IEEE
" » Redux the beginners guide!." Gianni Castellano | Sciencx [Online]. Available: https://www.scien.cx/2024/08/22/redux-the-beginners-guide/. [Accessed: ]
rf:citation
» Redux the beginners guide! | Gianni Castellano | Sciencx | https://www.scien.cx/2024/08/22/redux-the-beginners-guide/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.