Reputation: 285
I have a mapped component that displays tournaments/matches, and i'm struggling to get my head around a way to let users filter the tournaments by 'league', but still display them all if no 'league' is selected.
I have used recoil/atom to share the state of 'leagueFilter' to the component.
I tried using if
statement to render my JSX, but running into multiple problems.
import { FunctionComponent, useEffect, useState } from "react";
import { leagueState } from "../pages/trainer/[id]";
import { useRecoilState } from "recoil";
import PContainer from "./PContainer";
type Props = {
tournament: Tournament;
};
const TournamentContainer: FunctionComponent<Props> = ({ tournament }) => {
const [leagueFilter] = useRecoilState(leagueState);
if (tournament.league === leagueFilter) {
return (
<Box key={tournament.bout + tournament.league}>
<Box w="fit-content" m="auto" textAlign="center">
<Text fontSize="xl">{tournament.league}</Text>
<Text>{tournament.bout}</Text>
</Box>
<Flex
key={tournament.bout}
wrap="wrap"
w="auto"
m="auto"
justify="center"
>
{tournament.mon.map((mon, index) => (
<>
<PContainer key={mon.name + (index + 1)} {...mon} />
</>
))}
</Flex>
<Text align="center">{`Score:
${tournament.wins} - ${tournament.losses}`}</Text>
</Box>
);
} else {
return (same JSX as above);
}
};
export default TournamentContainer;
This, sort of works, but only on the first render, and TS gives me the error:
Type 'undefined' is not assignable to type 'ReactElement<any, any> | null'.ts(2322)
Upvotes: 0
Views: 247
Reputation: 1914
Don't do it in the child do it in the parent.
If leagueFilter has been set filter the tournaments with a .fitler
if it hasn't just render them all.
Something like this:
const Tournaments = ({tournmanets}) => {
const [leagueFilter, setLeagueFilter] = useRecoilState(leagueState);
let tournys = tournaments;
if (leagueFilter != null) {
tournys = tournmanets.filter( t => t.league == leagueFiler);
return <div>{tournys.map(t => <TournamentContainer tournmanet={t}/>}</div>;
})
Upvotes: 2