skip to Main Content

I am having trouble figuring out how to reset my projectList to it’s initial state so that way in the filterProjects function it is filtering through the entire projectList and not the already filtered ones. I have a function called resetProjects, just not sure where to call it so that the displayProject function works as it should.

Here is my code:

import './Projects.css';
import AllProjectList from '../../projectLists/AllProjectList.json'; 
import Project from '../../components/Project/Project';  
import Circles from '../../components/Circles/Circles'; 
import { useState, useEffect } from 'react';

const Projects = () => {
    const [projectList, setProjectList] = useState(AllProjectList.projects); 
    let givenValue = ""; 

    const getValue = (event) => { 
        givenValue = event.target.value.toString(); 
        filterProjects(givenValue); 
    };  

    const filterProjects = (value) => {
        setProjectList(projectList.filter(project => project.framework === value));
    }; 

    const resetProjects = () => {
        setProjectList(AllProjectList.projects); 
    }; 

    const displayProjects = () => {
        return (
            projectList.map((project) => {
                return ( 
                    <Project 
                        key={project.title}
                        title={project.title} 
                        description={project.description} 
                        url={project.url}
                        imagepath={project.imagepath}
                        role={project.role}
                        company={project.company}
                        framework={project.framework}
                        technologies={project.technologies}
                        workexamples={project.workexamples}
                    />
                )
            })
        )
    }

    return ( 
        <div className="project-container fadeIn">
            <div className="project-header">
                <h2>Projects</h2>
                <p>I love working with a team in a fast paced environment. I tend to take charge, always keep busy and maintain a positive attitude. </p>
                <div className="project-button-container">
                    <button className="custom-btn fill" value="Custom" onClick={getValue}><p>See Custom Projects</p></button>
                    <button className="custom-btn fill" value="Wordpress" onClick={getValue}><p>See WordPress Projects</p></button>
                    <button className="custom-btn fill" value="Magento" onClick={getValue}><p>See Magento Projects</p></button>
                    <button className="custom-btn fill" onClick={resetProjects}><p>See All Projects</p></button>
                </div>
            </div>
            <Circles/>
            <div className="project-list-container">
                {displayProjects()}
            </div>
        </div>
     );
}
 
export default Projects;

The code above works when clicking the buttons for the first time since the filterProjects function is looking through the entire array. However, if I click another button, it shows 0 projects because the function is only looking through the already filtered array. I need to reset the array to the original state before filtering on each button click. However, every time I do, I create an infinite state loop because I am calling the setProjectList function too many times.

2

Answers


  1. I have a little trick I use whenever I want to use search on a list on my page. the only change you need to make is to have another state that takes the same data projectList is taking

    const [projectList, setProjectList] = useState(AllProjectList.projects);
    const [defaultList, setDefaultList] = useState(AllProjectList.projects);
    

    Then in your filtersProject function can look like this

    const filterProjects = (value) => {
        const filteredList = defaultList.filter(project => project.framework === value));
        setProjectList(filteredList);
    }; 
    

    while your reset function can look like this

    const resetProjects = () => {
        setProjectList(defaultList); 
    }; 
    

    I hope this helps in your journey to finding a solution to your problem

    Login or Signup to reply.
  2. I recommend that you don’t change the list state at all when you filter; leave it as the full list. The filtered list can be calculated during rendering based on the states. If performance is a concern you can wrap this calculation in a useMemo, so it is only recalculated when the filter or full list changes:

    const [projectList, setProjectList] = useState(AllProjectList.projects);
    const [filter, setFilter] = useState(null);
    
    const filteredList = useMemo(() => {
       if (filter === null) {
         return projectList;
       } else {
         return projectList.filter(project => project.framework === filter);
       }
    }, [projectList, filter]);
    
    // ...
    const filterProjects = (value) => setFilter(value);
    
    const resetProjects = () => setFilter(null);
    
    // ...
    const displayProjects = () => {
      return filterProjects.map( // <---- loop over the filtered list
    // ...
    

    If this results in you never calling setProjectList then you can delete the projectList state, and just use AllProjectList.projects directly.

    const filteredList = useMemo(() => {
      if (filter === null) {
        return AllProjectList.projects
      } else {
        return AllProjectList.projects.filter(project => project.framework === filter);
      }
    }, [filter]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search