skip to Main Content

i’m fairly new to the React Js and can’t seem to get my head around prop drilling, the issue i have here is i want to console log the respective card id’s when i click on the delete button and then later filter them out and change the state…

  • i did try to pass id as an argument but then it throws an error saying handleDelete is not a function

App.jsx

import './App.css'
import { useState } from 'react'
import Header from './components/Header'
import FeedbackData from './data/FeedbackData'
import FeedbackList from './components/FeedbackList'
import FeedbackStats from './components/FeedbackStats'

function App() {
    const [feedback, setFeedback] = useState(FeedbackData)
    const handleDelete = (id) => {
        console.log(123)
    }
    return (
        <>
            <Header></Header>
            <div className='container col-12  col-sm-10 col-md-6 col-lg-7'>
                <FeedbackStats feedback={feedback}></FeedbackStats>
                <FeedbackList feedback={feedback} handleDelete={handleDelete}></FeedbackList>
            </div>
        </>
    )
}

export default App

FeedbackItem.jsx

import Card from './shared/Card'
function FeedbackItem({ item, handleDelete }) {
    return (
        <>
            <div className='feedback-item'>
                <Card item={item} handleDelete={handleDelete}></Card>
            </div>
        </>
    )
}

export default FeedbackItem


FeedbackList.jsx


function FeedbackList({ feedback, handleDelete }) {
    if (!feedback || feedback.length === 0) {
        console.log('no feedback')
    }

    return (
        <>
            {feedback.map((item) => (
                <FeedbackItem
                    key={item.id}
                    item={item}
                    handleDelete={handleDelete}></FeedbackItem>
            ))}
        </>
    )
}

export default FeedbackList

card.jsx

import { FaTimes, FaEdit } from 'react-icons/fa'
function Card({ item, handleDelete }) {
    return (
        <>
            <div className='card'>
                <div className='card-body'>
                    <div className='rating-badge' id='rating'>
                        {item.rating}
                    </div>
                    <div className='buttons'>
                        <button className='btn'>
                            <FaEdit></FaEdit>
                        </button>
                        <button onClick={handleDelete} className='btn'>
                            <FaTimes></FaTimes>
                        </button>
                    </div>
                    <p className='card-text'>{item.feedbackText}</p>
                </div>
            </div>
        </>
    )
}

export default Card

2

Answers


  1. If you’re going to pass an argument to an event handler and bind it, you have to use below syntax;

    handleDelete={() => handleDelete(id)}
    

    For comparision,

    This will fire your event when it's clicked
    onClick={handleDelete}
    
    This will fire your event when it's clicked with the given arguments
    onClick={() => handleDelete(id)}
    
    This will fire ALWAYS. Even if you don't click it. Because you're not binding the function, 
    you are calling it.
    onClick={handleDelete(id)}
    
    Login or Signup to reply.
  2. Here i’m assuming that you want to pass argument from component to handleDelete() Function.

    In Card Component:

    import { FaTimes, FaEdit } from 'react-icons/fa'
    function Card({ item, handleDelete }) {
        return (
            <>
                <div className='card'>
                    <div className='card-body'>
                        <div className='rating-badge' id='rating'>
                            {item.rating}
                        </div>
                        <div className='buttons'>
                            <button className='btn'>
                                <FaEdit></FaEdit>
                            </button>
                            <button onClick={()=>handleDelete("123")} className='btn'>
                                <FaTimes></FaTimes>
                            </button>
                        </div>
                        <p className='card-text'>{item.feedbackText}</p>
                    </div>
                </div>
            </>
        )
    }
    
    export default Card
    

    Here:

    onClick={()=>handleDelete("123")}
    

    when you are trying to pass function as props which takes argument. Then you have to call your function inside arrow function with argument as shown above.

    if you want to pass argument from App.js component:

    <FeedbackList feedback={feedback} handleDelete={()=>handleDelete("123")}></FeedbackList>
    

    Note: By using the Context API and Hooks, you can avoid prop drilling and directly access the shared data in any component that needs it, making your application more maintainable and easier to refactor.

    Let me know if anything doesn’t works here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search