Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does this state's object property show undefined?

So im using redux for state management for a React App. I’m getting some data from my API and set the response to the state.

State object looks like this:

export type TrendingState = [{
  id: string;
  points: number;
  name: string;
}]

Initial value is set to empty strings and 0 for the number prop:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const initialState: TrendingState = [
{
    id: '',
    points: 0,
    name: '',
},
];

Finally im using store to create a slice for dispatching the method in my component:

export const trendingSlice = createSlice({
name: 'trending',
initialState,
reducers: {
    setTrendingPlayers: (state, action: PayloadAction<TrendingState>) => {
        Object.assign(state, action.payload);
        
        state = action.payload;
     
        //console log the state to see what it looks like
        console.log(state);
    },
    }
  },
);


export const { setTrendingPlayers } = trendingSlice.actions;
export default trendingSlice.reducer;

Now in my component i can use id and name in my functions just fine but the number prop returns undefined. When i log the state as a whole it does show that number actually has a value for every object. I’m thinking that in some way i’m probably trying to use number before load but it is being used in the same mapping as name and id, so why arent they undefined aswell?

My component as a whole:

import { useAppSelector } from "../context/hooks";
import { useAppDispatch } from "../context/hooks";
import api from "../api";
import { SetStateAction, useEffect, useState } from "react";
import { setTrendingPlayers } from "../context/trendingSlice";
import { getPlayerImage } from "../constants/Images";

function Home() {

const playerState = useAppSelector(state => state.player);
const trendingState = useAppSelector(state => state.trending);
const dispatch = useAppDispatch();
const [points, setPoints] = useState(0);

async function getTrendingPlayers(){  
    dispatch(setTrendingPlayers(await api.getTrendingPlayers()));
}
   
useEffect(() => {
    getTrendingPlayers();
}, [])

const logo = require('../assets/defaulticon.png')
return (
    <>
   
   <section>
  <div className='header-image'>
    <div className='header-content'>
      
    </div>
  </div>
    <h2 className="trending-titleh2">TRENDANDE SPELARE</h2>
    <h3 className="trending-titleh3">SENASTE 5 MATCHERNA</h3>
  <div className='trending-players'>
    
    {trendingState.map((player, index) => {
        if (index < 3) {
            return (
                
                <div className='trending-player-box'>
                    <div className="trendinglogo">
                    {getImage(player.id)}
                    </div>

                    <h3>{player.name!.split(",")[1]} {player.name!.split(",")[0]}</h3>
                    <h3>{player.points}</h3>

                </div>
            )
        }
    })}

    </div>
    <div className='shl-news'>
        <div className='shl-news-box'>

        </div>
    </div>

    
</section>
    </>
);
}

function getImage(id: string) {
  return getPlayerImage(id);
}

export default Home;

I’m probably missing something obvious here but any help from some non-tired eyes would be appreciated 🙂

>Solution :

It looks like the issue is with the code that sets the state in the setTrendingPlayers reducer.

When using Object.assign to update the state, the first argument is the target object, which in this case is the current state. The second argument is the source object, which is the action.payload. However, Object.assign only updates the enumerable properties of the target object, and it does not modify the original object. Instead, it returns a new object.

You are then overwriting the value of state with the value of action.payload, but the original state object is not modified. You can fix this by using the return value of Object.assign instead of overwriting state.

Here is how you can update the setTrendingPlayers reducer to fix the issue:

setTrendingPlayers: (state, action: PayloadAction<TrendingState>) => {
    // Use the return value of Object.assign to update the state
    return Object.assign(state, action.payload);

    // Remove this line, since it overwrites the value of state
    // state = action.payload;

    //console log the state to see what it looks like
    console.log(state);
},

I hope this helps!

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading