'How to modify react button "More"?
I have the following React component:
import React from "react";
import { useState, useEffect } from "react";
import { TailSpin } from "react-loader-spinner";
function Pokemon({ name, url }) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then((r) => r.json())
.then(setData);
}, [url]);
const onClickButtonChange = () => {
let cardMore = document.querySelector(".card_more");
let cardMain = document.querySelector(".card_main");
cardMore.style.display = "block";
cardMain.style.display = "none";
};
return (
<div>
{data ? (
<div>
<div className="card card_main">
<div className="animate__animated animate__bounceInUp">
<div className="card-image">
<img src={data.sprites.front_default} alt="pokemon_img" />
<span className="card-title">{name}</span>
<button onClick={onClickButtonChange}>More</button>
</div>
<div className="card-content">
{data.abilities.map((n, index) => (
<p key={index}>{n.ability.name}</p>
))}
</div>
</div>
</div>
<div className="card card_more">
<p>{data.height}</p>
<p>{data.weight}</p>
</div>
</div>
) : (
<div>
<TailSpin type="Puff" color="purple" height={100} width={100} />
</div>
)}
</div>
);
}
export { Pokemon };
My implementation of the More button needs to display additional features (the card_more block). Right now this function only works on the very first element. I understand that in React this can most likely be done more correctly, but I don’t know how, so I use CSS styles.
P.S Edited:
I tried to use React features, maybe someone can tell me or does it make sense?
import React from "react";
import { useState, useEffect } from "react";
import { TailSpin } from "react-loader-spinner";
function Pokemon({ name, url }) {
const [data, setData] = useState(null);
const [show, setShow] = useState(false);
useEffect(() => {
fetch(url)
.then((r) => r.json())
.then(setData);
}, [url]);
const handleMore = async () => {
if (show === true) {
setShow(false);
} else if (show === false || !data) {
const r = await fetch(url);
const newData = await r.json();
setData(newData);
setShow(true);
}
};
return (
<div>
{data && show ? (
<div>
<div className="card card_main">
<div className="animate__animated animate__bounceInUp">
<div className="card-image">
<img src={data.sprites.front_default} alt="pokemon_img" />
<span className="card-title">{name}</span>
</div>
<div className="card-content">
{data.abilities.map((n, index) => (
<p key={index}>{n.ability.name}</p>
))}
</div>
</div>
<button onClick={handleMore}>More</button>
</div>
<div className="card card_more">
<p>{data.height}</p>
<p>{data.weight}</p>
</div>
</div>
) : (
<div>
<TailSpin type="Puff" color="purple" height={100} width={100} />
</div>
)}
</div>
);
}
export { Pokemon };
Solution 1:[1]
Youre right, this isn't the way you should do it in React. But your problem in your onClickButtonChange-Function is that youre only getting one element with document.querySelector(".card_more") and everytime you call it you get the same element back (No matter on which card you call it)
What you need to do is: Identify the single component elements. Thats most likely solved by passing a id/key value down via props and then putting this id on a parent-element (e.g. div.card) and you give it an id:
<div className="card card_main" id={props.keyvalue}>
....
</div>
And then in your onClickButtonChange-Function you call:
let cardMore = document.querySelector(`#${props.keyvalue} .card_more`);
...
This should give you the right element.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Raqha |
