I have a parent component containing an array and I am mapping to create multiple cards something like this->
const Users = [
{
id: 1,
name: "abc",
age: 12,
},
{
id: 2,
name: "def",
age: 22,
},
{
id: 3,
name: "abf",
age: 32,
},
];
{Users.map((h, index) => {
return (
<React.Fragment key={index}>
<User data={h} />
<br></br>
</React.Fragment>
);
})}
User.js
import { useState } from "react";
import "./style.css";
function User(user) {
const [copyTxt, setCopyTxt] = useState("Copy");
const [copyClass, setCopyClass] = useState("button_copy");
const handleCopy = () => {
setCopyTxt("Copied!");
setCopyClass("button_copied");
};
return (
<div className="user_div">
<div className="p-2 flex-fill button_div">
<button type="submit" onClick={handleCopy} className={copyClass}>
{copyTxt}
</button>
</div>
</div>
);
}
export default User;
current result
->
if all 3 buttons are clicked one by one, for all 3 buttons text changes to Copied!
expected result
->
if all 3 buttons are clicked one by one, the last button clicked should be the only one that shows Copied!
, but Other buttons should show Copy
.
How do I achieve that?
2
Answers
The solution is life the state up.
Logic is simple store the active id at one place.
You can do this
First you create a state in the parent component from the array and add the property
isCopied
to each one and set it default tofalse
:Also there, you create the function that takes the id of the user from the child component and set its property
isCopied
totrue
butfalse
for all others:Now to each child you pass as props, data ( the user +
isCopied
property) and also thehandleCopy
function:Finally, in the child component, you want to update its state (
copyTxt
andcopyClass
) each time propertyisCopied
of the passed user (data
) is updated: