How to filter array in ReactJS without affecting original array

I am currently completing a challenge on Frontend Mentor, which is the Todo List challenge. However, I am having trouble with the task filtering function (showing only the completed tasks, only the uncompleted tasks, or showing all the tasks).
Here is my code

Tasks container

import { useState } from "react"

import iconCheck from '../images/icon-check.svg'

import TaskComponent from "./TaskComponent.jsx"

import Footer from "./Footer"

const Tasks=({tasks, display, removeMethod,})=> {

    const  [task,setTask]  = useState(tasks)

   

    const filterFunction=(event)=> {

        let filtered;

        const target = event.target;

        switch(target.innerHTML) {

            case('All'):

                filtered = task

            break;

            case('Active'):

                filtered = task.filter(()=> {

                    return !task.completed

                })

            break;

            case('Completed'):

                filtered = task.filter(()=> {

                    return task.completed

                })

            setDisplay(filtered)

        }

    }

    return(

        <div className="tasks">

           

            {display.map(el=> {

                return (

                    <TaskComponent task={el} removeMethod = {removeMethod} key = {el.id}></TaskComponent>

                )

            })}

            <Footer  method = {filterFunction} ></Footer>

           

        </div>

       

    )

 

}

export default Tasks;

Footer component (where the filter buttons are)


const Footer=({ method})=> {

    return(

    <div className="footer">

        <h5> tasks left</h5>

            <div className="selectors">

                <h5 onClick={(event)=> {

                   method(event)

                }}>All</h5>

                <h5 onClick = {(event)=> {

                    method(event)

                }}>Active</h5>

                <h5 onClick={(event)=> {

                    method(event)

                }}>Completed</h5>

            </div>

        <h5>Clear Completed</h5>

    </div>

    )

   

}

export default Footer;

Things i have tried:

  • setting a duplicate array using useState (so that i can keep the original while filtering the duplicate), however it was a bit challenging for me to implement and it ended up not updating.

for more details, here is the challenge. Frontend Mentor | Todo app coding challenge

Sorry for the rather long post, I am quite stupid and have been stuck with this problem since yesterday

I’m confused. What is setDisplay? Where does it come from? What is display? Some of your naming is confusing - you initials task with tasks? Which is it, one task or more than one?

The basic concept of what you’re thinking looks fine. I just don’t understand the implementation. I would expect some local state, not “task” but like “filteredTasks”. And then that is what you would save the filtered tasks into. And that is what you would map over to display them.

1 Like

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

1 Like

Kevin is right, setDisplay comes out of nowhere, maybe you ment to use setTask?
I dont like that you use h5 elements to click and cause some effect. It would be better to use buttons and style them. Also, it seems redundant to pass the event object and use its data to determine your actions, when you could simply pass the key-words directly to the “method” function. It would make things lot more simple for you.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.