I have a list of elements where each element is a Game
and as I toggle I dispatch an action to my slice where I want to affect the value of isDivOpen
but just for the element (Game
) I clicked on.
I created the following slice:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
const initialState = {
games: [],
isLoading: false,
isDivOpen: true,
};
export const gameSlice = createSlice({
name: 'games',
initialState,
reducers: {
toggleSeeMore(state, action) {
const gameId = action.payload;
console.log(gameId);
},
},
})
export const { toggleSeeMore } = gameSlice.actions;
export default gameSlice.reducer;
And the following is my component:
import React from 'react';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import '../../styles/components/Games/Game.css';
import { useSelector, useDispatch } from 'react-redux';
import { toggleSeeMore } from '../../slices/gameSlice';
function Game({ game }) {
const { name, description, employees, hours, photo } = game;
const isDivOpen = useSelector(state => state.games.isDivOpen);
const dispatch = useDispatch()
const toggleMenu = () => {
const gameId = game._id
dispatch(toggleSeeMore(gameId))
}
return (
<div className='game_card'>
<div className="game_heading">
<div className="image_container">
<img src={`http://localhost:5000/uploads/${photo}`} alt="no photo" />
</div>
<h1>{name}</h1>
</div>
<div className="game_content">
<p className="description">{description}</p>
<div className="game_hours">
{formattedTimes.map((time, index) => (
<div key={index}>{time}</div>
))}
</div>
</div>
<button onClick={toggleMenu}>See More<ExpandMoreIcon/></button>
<div className={`employees ${isDivOpen ? 'show' : 'hide'}`}>
<p>Employees</p>
{employees.map((employee, index) => (
<div key={index}>{employee}</div>
))}
</div>
</div>
);
}
export default Game;
I am receiving the correct id of the game I’m clicking on, but I don’t know how to change the value of isDivOpen
just for that game.
3
Answers
This could be more simple than it is currently,
Reducers could be helpful for large and complex state management but for the thing that show or hide is not really necessary
You can delete the isDivOpen in redux state, then you can declare an useState for that in your component and hide or show based on that state… it will affect item individually
Also in your JSX you can approach the show or hide like this (only another way to tackle this)
That being said if you want to still show or hide each one using the reducer you has to basically change your structure and each game has to have the value related to if it is open or not
Hope it helps
You are on the right track. Instead of using
isDivOpen
as a boolean value though, you should store the passedgameId
or null when deselecting the game. The UI will check the currentopenGameId
value against its own game id value, and set the appropriate conditional value.Example:
if you want to do it with the redux way ( not recommended ) then just update the reducer toggleSeeMore and add variable gameId to initial state.
Recommended way, create a local state in the Game component,