React component doesnnt re render

224 views Asked by At

im passing values using react redux everything is passed but the component i want to render only renders 1 time and when i save my code in vscode (it renders again)the data renders on page like it should

return (
    <div className='fav-container' id='favorites'>

    {FavoritesData.data.length === 0 ? (
            <h5>You Don't Have Any Favorites Yet!</h5>
        ) : (
            <div className="favorites-grid">{FavoritesData.data.map((item) =>  <Favorite item={item} />)}</div>
        )}


    
      <button onClick={() => console.log(FavoritesData.data.length)}></button>
    </div>
);

on the log the data updates but the trenary function dont trigger same goes for useEffect

2

There are 2 answers

0
Wes Harper On

Are you overwriting data or just updating it? If you're just updating in-place, the reference won't change. I don't have quite enough information to make this diagnosis, but I'm suspecting that you're seeing the same behavior in React as you'd see here:

// in the example below, the two variables are essentially storing the exact same array, not copies of the same array
const myArr = [1, 2, 3];
// storing a reference to the myArr array
const myOtherArr = myArr;

myOtherArr.push(4);
console.log(myArr); // prints [1, 2, 3, 4]

// in this example, the arrays are different
const myArr = [1, 2, 3];
// store a copy of all the values from myArr in a new array literal
const myOtherArr = [...myArr];

myOtherArr.push(4);
console.log(myArr) // prints [1, 2, 3]

In React, which enforces a functional approach, you'd want to overwrite FavoritesData.data entirely, otherwise the reference won't actually change and React will think that it's looking at the exact same array. If you suspect that this is a misdiagnosis or if you still have questions, please post the code that updates FavoritesData.data and I'll update my answer.

4
Dean On

The problem is not in updating the values the problem its not looping through the components

I update it with redux, reducer:

        case 'ADD_FAVORITES':
            state.data.push(action.payload)
            return state 
            
        case  'DEL_FAVORITES':
        let favoritesArr = [ ...state.data ];
        state.data = favoritesArr.filter(fav => fav.cityName !== action.payload.cityName);  
        return state
        
    default:
        return state
  }
}

The click useEffect in the other component

useEffect(() => {
       
           const fav = {
                cityName:CityData.EnglishName,
                TemperatureMetricValue:WeatherData.TemperatureMetricValue,
                TemperatureImperialValue: WeatherData.TemperatureImperialValue,
                WeatherText: WeatherData.WeatherText}
            
            const FavoritesPromise = async (favorites) => {


                return favorites;
            }              
       
         
         isClick ?  
             FavoritesPromise(fav)
            .then(data=>{

            dispatch(addFavorites(data))
            localStorage.setItem('location',JSON.stringify(FavoritesData.data))
             }) 
            .catch(err => console.log(err)) 

            :  FavoritesPromise(fav)
            .then(data=>{
                FavoritesData.data.map((item) => {
                    if(item.cityName == CityData.EnglishName){
                        dispatch(delFavorites(item))
                        localStorage.setItem('location',JSON.stringify(FavoritesData.data))


                    }

                })

             }) 
            .catch(err => console.log(err))

    },[isClick])

Now when I try to return the value to the html it doesn't render it but when I log the values it seems like it is passing it.

 return (
    <div className='fav-container' id='favorites'>

    {FavoritesData.data.length === 0 ? (
            <h5>You Don't Have Any Favorites Yet!</h5>
        ) : (
            <div className="favorites-grid">{FavoritesData.data.map((item) =>  <Favorite item={item} />)}</div>
        )}

When I log the length it is changing, I tried the same logic with useEffect when the lengths changes and its not triggering as well.

      <button onClick={() => console.log(FavoritesData.data.length)}></button>
    </div>
 );
};