score:1

Accepted answer

so i had a little bit of trouble getting the codesabox to work. i still found the issue though. there's two big issues. original:

const handlechange1 = (e) => {
  if (e.target.checked) {
    setlearningdirection([...learningdirection, e.target.value]);
  } else {
    setlearningdirection(
      learningdirection.filter((id) => id !== e.target.value)
    );
  }

  if (e.target.checked) {
    settargetaudience([...targetaudience, e.target.value]);
  } else {
    settargetaudience(targetaudience.filter((id) => id !== e.target.value));
  }
};

you shouldn't have this all in one function. with the way this works now, each checked input is getting assigned to both filters (which only break the first filter because of the useeffect). a good rule of thumb to follow is to have each setstate tied to one function (sometimes that unavoidable, but that's what i would do here). here's what i mean. solution:

const handlelearningdirectionchange = (e) => {
  if (e.target.checked) {
    setlearningdirection([...learningdirection, e.target.value]);
  } else {
    setlearningdirection(
      learningdirection.filter((id) => id !== e.target.value)
    );
  }
};

const handletargetaudiencechange = (e) => {
  if (e.target.checked) {
    settargetaudience([...targetaudience, e.target.value]);
  } else {
    settargetaudience(targetaudience.filter((id) => id !== e.target.value));
  }
};
// todo: change the onchange inside the forms

you also have a 2nd problem inside the useeffect. original:

useeffect(() => {
  if (learningdirection.length === 0) {
    setfilteredlist(searchlists);
  } else {
    setfilteredlist(
      searchlists.filter((filterlist) =>
        learningdirection.some((category) =>
          [filterlist.learningdirection].flat().includes(category)
        )
      )
    );
  }

  if (targetaudience.length === 0) {
    setfilteredlist(searchlists);
  } else {
    setfilteredlist(
      searchlists.filter((filterlist2) =>
        targetaudience.some((category) =>
          [filterlist2.targetaudience].flat().includes(category)
        )
      )
    );
  }
}, [learningdirection, targetaudience]);

the 2nd setfilteredlist() is just going to overrite the first. so the learningdirection filter isn't doing anything. this fix is a little more messy, but it does work. solution: (edit: initialize set with searchlists, and change filters to look for deletions. also removed if unnecessary if statements)

  useeffect(() => {
    const set = new set([...searchlists]);

    learningdirection.foreach((direction) => {
      searchlists.foreach((item) => {
        // change this to "===" if you want the opposite result
        if (item.learningdirection !== direction) {
          set.delete(item);
        }
      });
    });

    targetaudience.foreach((audience) => {
      searchlists.foreach((item) => {
        // change this to "===" if you want the opposite result
        if (item.targetaudience !== audience) {
          set.delete(item);
        }
      });
    });

    setfilteredlist([...set]);
  }, [learningdirection, targetaudience]);

we're using a set to avoid duplicate values, looping over the checked values, then looping over the searchlist to get the results. that happens first then we assign the results to the state (using the ... operator so we turn the set into an array).

overall, part of me wants to completely refactor this component. the solutions here should get you up and running to move forward, but i feel as though there's a lot of unnecessary complexity in how you're handling things. i'd have to spend a lot more time trying to understand what's going on to be really sure of that and provide a better alternative though.

edit2: providing two alternatives

my guess is that this is how you want the filters:

    // have all the results
    const set = new set([...searchlists]);

    // remove unselected check boxes (if any are selected)
    if (learningdirection.length) {
      searchlists.foreach((item) => {
        if (!learningdirection.includes(item.learningdirection)) {
          set.delete(item);
        }
      });
    }

    // remove more unselected check boxes (if any are selected)
    if (targetaudience.length) {
      searchlists.foreach((item) => {
        if (!targetaudience.includes(item.targetaudience)) {
          set.delete(item);
        }
      });
    }

    setfilteredlist([...set]);

or maybe this?

// start empty if there's any selected checkboxes
const set =
   learningdirection.length > 0 || targetaudience.length > 0
     ? new set()
     : new set([...searchlists]);

// add to empty set if any checkboxes are selected
if (learningdirection.length) {
  searchlists.foreach((item) => {
    if (learningdirection.includes(item.learningdirection)) {
      set.add(item);
    }
  });
}

// add more if any checkboxes are selected
if (targetaudience.length) {
  searchlists.foreach((item) => {
    if (targetaudience.includes(item.targetaudience)) {
      set.add(item);
    }
  });
}

setfilteredlist([...set]);

Related Query

More Query from same tag