skip to Main Content

I can’t add the product to favorite page and get the above error.

I’m using React-Native with context hook to add the product to cart and favorite pages. The problem is all actions in reducer hook are working except add to favorite action is not working.

Context Code

const initialState = {
  products: ProductData, // productData is dummy data where i place all products with details
  cart: [],
  FavoritesList: [],
};
 
const reducer = (state = initialState, action) => {
  switch(action.type) {
    case 'ADD_PRODUCT_TO_FAVORITE':
      const product = action.payload;
      const index = state.products.findIndex((item)=> item?.id === product?.id)
      if (index >= 0) {
        state.splice(index, 1);
      } else {
        state.push(product)
      }

      return [...state,];

    case 'CLEAR':
      return {cart :[]}
           
    default:
      throw new Error(`unknow action.${action.type}`)
  }
}

favorite screen code

const Faviroute = () => {
  const { FavoritesList } = useCart();
  
  return (
    <View
      style={{
        // flex:1,
      }}
    >
      {(FavoritesList.length === 0) ?
        <View> 
          <Text>Get your favourite Coffee easily</Text>
        </View>   
      : <View> 
          {/*Card Container*/}
          <ScrollView>
            <View>
              {FavoritesList.map((item, index) => (         
                <View key={index}>           
                  <Text>{`Product Name: ${item.name}`}</Text>           
                  <Text>{`Size: ${item.size}`}</Text>           
                  <Text>{`Quantity: ${item.qty}`}</Text>           
                  <Text>{`Price: ${item.price}`}</Text>         
                </View>       
              ))}       
            </View>
          </ScrollView>
        </View>
      }
    </View>
  )
}

2

Answers


  1. Array splice and push methods mutate the existing array reference. Create shallow copies then overwrite. In this case if you would like to remove an element then filter the current state, and when adding an element concatenate. Make sure you are updating and returning the correct state properties.

    Example:

    const reducer = (state = initialState, action) => {
      switch(action.type) {
        case 'ADD_PRODUCT_TO_FAVORITE':
          const product = action.payload;
    
          const index = state.FavoritesList.findIndex(
            (item)=> item?.id === product?.id
          );
    
          if (index !== -1) {
            return {
              ...state,
              products: state.FavoritesList.filter((_, i) => i !== index),
            };
          } else {
            return {
              ...state,
              products: state.FavoritesList.concat(product),
            };
          }
    
        case 'CLEAR':
          return { ...state, cart: [], FavoritesList: [] };
               
        default:
          console.log("unhandled action", { action });
          return state; // <-- just return current state
      }
    };
    

    Suggestion

    Instead of double-storing the product data, the "favorited" products should store just the product id. You can get back the complete favorites array derived from the products array filtered by products with a favorited id.

    Example:

    const initialState = {
      products: ProductData,
      cart: [],
      favorites: {},
    };
    
    const reducer = (state = initialState, action) => {
      switch(action.type) {
        case 'ADD_PRODUCT_TO_FAVORITE':
          const product = action.payload;
    
          return {
            ...state,
            favorites: {
              ...state.favorites,
              [product.id]: !state.favorites[product.id],
            },
          };
    
        case 'CLEAR':
          return { ...state, cart: [], favorites: {} };
               
        default:
          console.log("unhandled action", { action });
          return state; // <-- just return current state
      }
    };
    
    const { favorites, products } = useCart();
    
    const favoritesList = products.filter(product => favorites[product.id]);
    
    Login or Signup to reply.
  2. Can you try below mentioned code.

       const reducer = (state = initialState, action)=>{
            switch(action.type){
               case 'ADD_PRODUCT_TO_FAVORITE':
                const product = action.payload;
                const index = state.products.findIndex((item)=> item?.id === product?.id)
                if (index >= 0){
                     state.products.splice(index, 1);
                } 
                state.FavoritesList.push(product)
                return [...state,];
        
                case 'CLEAR':
                      return {cart :[]}
                   
                default:
                    throw new Error(`unknow action.${action.type}`)
            }
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search