Search code examples
javascriptreactjstypescriptrecoiljs

Using recoil selector to filter component data?


I feel like i've read so many examples/docs and watched videos but i can't get my head around using selectors with recoil. Maybe i'm just having a bad day cause i don't think it's that hard.

This is where i'm at...

lets say i have data like:

const data = [
  {
    name: "wiggles",
    type: "cat",
    age: "244",
  },
  {
    name: "wobbles",
    type: "dog",
    age: "55",
  },
  {
    name: "flobbles",
    type: "dog",
    age: "98",
  },
];

in my index i have:

export const typeFilterState = atom({
   key: 'typeFilterState',
   default: '',
});
const UserPage: NextPage<Props> = ({data}) => {

const [typeFilter, setTypeFilter] = useRecoilState(typeFilterState);

return(
<select onChange={(e) => setLeagueFilter(e.target.value)}>
<option value='cat'>Cat</option>
<option value='dog'>Dog</option>
<option value='elephant'>Elephant</option>
</select>

{
  data.map((d) => (
    <DataComponent data={d} />
  ))
}
)};

DataComponent would be like:

const DataComponent: FunctionComponent<Animals> = ({data}) => {
return (
   <Text>{data.name}</Text>
   <Text>{data.type}</Text>
   <Text>{data.age}</Text>
)
};

I want it so if users select cat it only shows data with cats, but also to show ALL data if nothing is selected...


Solution

  • There's a typo in your <select> onChange function:

    // <select onChange={(e) => setLeagueFilter(e.target.value)}>
    <select onChange={(e) => setTypeFilter(e.target.value)}>
    

    Just filter the array based on the typeFilter value before mapping as components:

    // data.map((d) => (
    //   <DataComponent data={d} />
    // ))
    
    data
      .filter(({type}) => {
        // nothing selected yet, keep all:
        if (!typeFilter.trim()) return true;
        // else keep if item.type equals filter:
        return type === typeFilter;
      })
      .map((d) => (
        <DataComponent data={d} />
      ))