Search code examples
reactjsreact-reduxsemantic-ui

How catch icon value,change value and color using semantic ui react


Using semantic ui , Initialize the prop at father component : isFavorite = false can't catch the value after clickig at icon , how i fill the star to diff color (by add attribute? styleColor={isFavorite : color:"red" : color:"white" })

component.js const ProductDetails = () => {

    const {productId} = useParams()
    
    const selectedProd = useSelector((state) => state.allProducts.products.find(product => 
        product.id === parseInt(productId)
        ));
    const products = useSelector((state) => state.allProducts.products)
    
  
    let {isFavorite} = selectedProd 
   
   
   const handleFavoriteSelect =(e)=>{
        isFavorite = !isFavorite
        selectedProd.isFavorite=isFavorite  
        dispatch(updateProducts(products,selectedProd))            

   }

return(
     <i onClick={e => handleFavoriteSelect(e)} className="right floated star outline icon" onChange={e=> console.log(!e.target.attributes.value)} value={isFavorite}></i>
)

redux/action.js

export const updateProducts = (products,product) => {
    const indexOfItem = products.findIndex(q => q.id === product.id);
    if (indexOfItem > -1) {
        products[indexOfItem] = product;
     }
    return {
        type: ActionTypes.SET_PRODUCTS,
        payload: products
    };
};

redux/reducer.js

export const productReducer = (state = initialState, { type, payload }) => {
   
    switch (type) {
        case ActionTypes.SET_PRODUCTS:
            //take state and update this with payload data
            return {...state,products:payload};
        default:
            return state;
    }

}

redux/reducer/index.js

import { combineReducers } from 'redux'
import { productReducer,selectedProductReducer } from './productReducer'

const reducers = combineReducers({
    allProducts: productReducer,
    product:selectedProductReducer
})

export default reducers

Solution

  • Try the following:

    style={isFavorite?{color:"red"}:{color:"white"}}
    

    I would suggest an edit to changing the product as well, you are currently mutating state like you've never read a line of documentation about redux or react:

    //toggleFavorite would be much more descriptive
    const handleFavoriteSelect =(e)=>{
      dispatch(updateProducts(products,{
        ...selectedProd,
        isFavorite:!selectedProd.isFavorite
      }))   
    }
    
    export const updateProducts = (products, product) => {
      return {
        type: ActionTypes.SET_PRODUCTS,
        payload: products.map(
          (currentProduct) =>
            currentProduct.id === product,id
              ? product //return changed product
              : currentProduct //return original product
        ),
      };
    };
    

    That still leaves you with way too much logic in your component and action creator, it would be better to define a TOGGLE_FAVORITE action type with the id as payload and let the reducer handle the logic of toggling favorite.