I have this state of array of object. I use them to create three cards.
const [option, setOption] = useState([{
id: 1,
label: "Borrowers",
icon: FcApprove,
counter: 2,
link: "borrowers",
color: "#5d8c6d",
isActive: false,
},
{
id: 2,
label: "My Offer",
icon: FaHandsHelping,
counter: 2,
link: "offer",
color: "#04738a",
isActive: false,
},
{
id: 3,
label: "Promise",
icon: FaPrayingHands,
counter: 2,
link: "promise",
color: "#40437a",
isActive: false,
}
]);
Whenever one of these cards is clicked, I would like to update the field isActive to true as follows.
function FixedHeader() {
const [options, setOptions] = useState(option); //option is the above mentioned array of object
const handleChange = (opt) => {
setOption([option[index].isActive: true])
}
return < > {
options.map((opt, index) => {
<Card onClick={handleChange(opt,index)} key={index} className={opt.isActive ? "activecard": ""}>
<CardContent>
<Stack direction="column">
<opt.icon size={20}/>
<Typography>opt.label</Typography>
</Stack>
</CardContent>
</Card>
})
}
My code somewhat looks the above one. but it is not literally changing isActive
filed
CodePudding user response:
You are mutating the options
array. When you want to update an array stored in state, you need to create a new one (or make a copy of an existing one), and then set state to use the new array.
Below will fix your issue
const handleChange = (options, index) => {
setOption(options.map((option, i) => ({...option, isActive: i === index }));
}
CodePudding user response:
options
is an array. You will want to map the previous state array to the next state array, updating the specific element object by the id
property.
const [options, setOptions] = useState(option);
// Curried function to close over option id in callback scope
const handleChange = (id) => () => {
setOption(options => options.map(option => option.id === id
? { ...option, isActive: true }
: option
);
}
options.map((opt) => (
<Card
key={index}
onClick={handleChange(opt.id)}
className={opt.isActive ? "activecard" : ""}
>
<CardContent>
<Stack direction="column">
<opt.icon size={20} />
<Typography>opt.label</Typography>
</Stack>
</CardContent>
</Card>
)