Home > Back-end >  I can't get array.filter to work with useState
I can't get array.filter to work with useState

Time:12-01

I am trying to delete an item from a shopping cart and I am using the filter hook to accomplish this. I have looked at the documentation for this and at the answers here on stack overflow. unfortunately no luck.

this is my code for the entire component. the function is of course "deleteItemFromBasket" and it is being called at the onclick on the delete button:

function CheckoutProduct({id, title, price, description, rating, category, image }) {
    const [basket, addToBasket] = useAppContext();

    const deleteItemFromBasket = (id) => {
        addToBasket(basket.filter((task) => task.id !== id));
    };

    return (
    <div>
        {basket.map((element) => {
            if (element === id) {
                return (
                    <div className='grid grid-cols-5 border-b pb-4'>
                         {/* far left */}
                        <Image src={image} height={200} width={200} objectFit='contain' />

                
                    {/* middle */}
                        <div className="col-span-3 mx-5">
                            <p>{title}</p>
                            <p className='text-xs my-2 line-clamp-3'>{description}</p>

                        <button onClick={deleteItemFromBasket} className='button'>delete</button>

                        <h1>items ID in basket: {basket}</h1>
                            <h1>length of array: {basket.length}</h1>
                        </div>

                    {/* right */} 
                        <div>
                            <p>${price}</p>
                        </div>    
                    </div>  
                )
            }
        })}
    </div>
  )
}

here is the code of the context provider

import React, { createContext, useContext, useState } from 'react';


const AppContext = createContext();

export function AppWrapper({ children }) {
  var [basket, addToBasket]= useState([]);

 
  return (
    <AppContext.Provider value={[basket, addToBasket]}>
      {children}
    </AppContext.Provider>

  );
}

export function useAppContext() {
  return useContext(AppContext);
}

CodePudding user response:

looks like basket is an array of ids, not an array of objects. Assuming that is the case, then you need to change your delete function to

const deleteItemFromBasket = (id) => {
  addToBasket(basket.filter((element) => element !== id));
};

This is assuming that addToBasket is actually just setting the basket, not just additive.

CodePudding user response:

I eventually got it to work and it took a combination of the two answers so thank you everyone for the help!

notice below that the function "deleteItemFromBasket" is the same as joe's post but it to get it to work I needed to add the function in the onClick like zehan's answer. I don't know why this works so if anyone has an explanation as to why I'll save the answer spot for it! thanks friends

import React from 'react';
import Image from 'next/image'
import { useAppContext } from '../state'


function CheckoutProduct({id, title, price, description, rating, category, image }) {
    const [basket, addToBasket] = useAppContext();

    const deleteItemFromBasket = (item) => {

        addToBasket((current) => current.filter((element) => element !== item));
    };


    return (
    <div>
        {basket.map((element) => {
            if (element === id) {
                return (
                    <div className='grid grid-cols-5 border-b pb-4'>
                         {/* far left */}
                        <Image src={image} height={200} width={200} objectFit='contain' />

                
                    {/* middle */}
                        <div className="col-span-3 mx-5">
                            <p>{title}</p>
                            <p className='text-xs my-2 line-clamp-3'>{description}</p>
                        {/* <button onClick={deleteItemFromBasket(element)} >delete item</button> */}
                        <button onClick={ ()=> deleteItemFromBasket(id)} className='button'>delete</button>
                        <h1>items ID in basket: {basket}</h1>
                            <h1>length of array: {basket.length}</h1>
                        </div>

                    {/* right */} 
                        <div>
                            <p>${price}</p>
                        </div>    
                    </div>  
                )
            }
        })}
    </div>
  )
}

CodePudding user response:

function CheckoutProduct({id, title, price, description, rating, category, image }) {
    const [baskets, addToBasket] = useAppContext();

 const deleteItemFromBasket = (id) => {
        addToBasket( baskets.filter((task) => task.id != id) );
    };

    return (
    <div>
        {baskets.map((basket) => {
                return (
                    <div className='grid grid-cols-5 border-b pb-4'>
                         {/* far left */}
                        <Image src={image} height={200} width={200} objectFit='contain' />

                
                    {/* middle */}
                        <div className="col-span-3 mx-5">
                            <p>{title}</p>
                            <p className='text-xs my-2 line-clamp-3'>{description}</p>

                        <button onClick={ ()=> deleteItemFromBasket( basket.id ) } className='button'>delete</button>

                        <h1>items ID in basket: {basket.id}</h1>
                            <h1>length of array: {basket.length}</h1>
                        </div>

                    {/* right */} 
                        <div>
                            <p>${price}</p>
                        </div>    
                    </div>  
                )
            }
        })}
    </div>
  )
}

you are mapping over the basket array and you are using basket istead of element and you are calling the function deleteItem whitout passing the id in it.

  • Related