So, I've got this view of animal cards called like this:
<AnimalsCard {...elephant}/>
<AnimalsCard {...hippo}/>
<AnimalsCard {...sugar_glider}/>
My AnimalCard code looks like this:
export const AnimalsCard = ({ id, animal, img }) => {
const { t } = useTranslation();
return (
<>
<CardContainer id={id} img={img}>
<CardContent>
<CardTitle>{animal}</CardTitle>
<CardButton to={`${id}`}>Dowiedz się więcej</CardButton>
</CardContent>
</CardContainer>
</>
)
};
And my animal objects look like that:
export const elephant = {
animal: 'Słoń indyjski',
id: 'slon_indyjski',
species: 'mammals',
img: require('../../../images/animals/mammals/elephant.jpg'),
occurance: '',
habitat: '',
diet: '',
reproduction: '',
conservationStatus: '',
funFactOne: ''
}
When I click the button, new page of the animal id opens up:
<Route path="/:id" component={AnimalsDetails} />
On AnimalsDetails page, I would like to display all of the animal object data. I unfortunately have no idea how to pass it because I'm a beginner and hardly know anything about props and stuff. My current approach is that in the AnimalsDetails I retrieve the ID using useParams();
export const AnimalsDetails = () => {
const [mammal, setMammal] = useState(null);
let { id } = useParams();
useEffect(() => {
const mammal = mammalsData.filter(thisMammal => thisMammal.id === id);
setMammal(mammal);
// console.log(mammal[0].animal);
}, [id]);
return ( <AnimalsDetailsContainer>
{/* <div>{mammal[0].id}</div> */}
</AnimalsDetailsContainer>
)
};
export default AnimalsDetails;
And then using the ID from URL, I'm filtering my mammalsData array that I've created only to test if the approach works (I wish I could use the previously created objects but I don't know if it's possible). It looks like that:
export const mammalsData = [
{
[...]
},
{
animal: 'abc',
id: 'fgh',
species: 'idontknow',
img: require('whatimdoing.JPG'),
occurance: '',
habitat: '',
diet: '',
reproduction: '',
conservationStatus: '',
funFactOne: ''
}
];
For now it works only when I'm on the animals card page and click the button, so the ID is present. If I'm somewhere else on the page and my ID is not declared yet, I receive an error that the data I want to display is undefined, which makes sense obviously. I've tried wrapping the return of the AnimalsDetails to log an error if the ID is not present but it didn't work.
I know there is some decent way to do that (probably with props or hooks defined differently), but I really tried many stuff and I'm utterly lost now. I wish I could pass the data to AnimalsDetails within clicking the button or something but have no idea how to do that. :-(
I'll be grateful for any help. I know it's basic stuff, but it's my first website ever.
CodePudding user response:
I understand your problems. In my opinion you 'd like to focus useEffect method as below.
useEffect(() => {
if(id != undefined)
// console.log('error);
return (
<div>{'error'}</div>
);
const mammal = mammalsData.filter(thisMammal => thisMammal.id === id);
setMammal(mammal);
// console.log(mammal[0].animal);
}, [id]);
CodePudding user response:
Try this way
<Route path="/:id" render={()=> <AnimalsDetails {...myProps} />} />
CodePudding user response:
If you are using the latest react router (v6), use element
instead of render
(here):
<Route path="/:id" element={<AnimalsDetails animal={yourAnimal} />} />