so I am declaring a usestate variable as "count" and I am mapping through a list of 2 items. This code shows the variable declaration and the function to increment and decrement
const [count, setCount] = useState(1);
const increment = () => {
setCount((prev) => prev + 1);
};
const decrement = () => {
setCount((prev) => {
if (prev == 1) return prev;
return prev - 1;
});
};
And the next code shows how I am mapping through an item and displaying a text that holds the count variable
{
cartItemArr.map((entry: any, index: number) => {
return (
<Flex
key={index}
w={'100%'}
alignItems={'center'}
justifyContent={'space-between'}
>
<Flex direction={'column'} justifyContent={'space-between'}>
<Text fontWeight={600} fontSize={'14px'} textColor={'#000'}>
{entry?.foodId.nameOfFood}
</Text>
<Text fontWeight={400} fontSize={'12px'} textColor={'#000'}>
#{entry?.foodId.pricePerServing}
</Text>
</Flex>
<HStack
justify={'center'}
w="109px"
borderRadius={'40px'}
py="8px"
border={'1px solid #AA9F93'}
>
<AiOutlineMinus cursor={'pointer'} onClick={decrement} className='cursor-pointer' />
<Text>{count}</Text>
<AiOutlinePlus cursor={'pointer'} onClick={increment} className='cursor-pointer' />
</HStack>
</Flex>
)
})
}
So when I click on the first item, the second item also increases. I know that it is because both of them have the count variable which is why it is behaving like that, is there something I can do that will make the counts not affect each other on the mapped items? I hope I can communicate my issue well. For better context, this is the screen I am building;
3
Answers
Recognize that when, in JSX, you do:
the
[[SOME_CODE_HERE]]
is actually a React component. If you want to track state for each iteration of that.map()
, then consider putting state (i.e. useuseState()
) inside[[SOME_STUFF_HERE]]
.And…to be a better/cleaner codebase, move the definition of
[[SOME_CODE_HERE]]
to its own file (e.g.SomeCodeHere.jsx
) so that it is clear that this is a component, and that it be maintained as such.Create a separate React component for the individual entries, something like this:
That way the count variable is local to each entry rather than to the entire cart.
Then update your map to something like this:
You are using the same variable
count
for all entries. So, when you change in one place, it will change in all other places because the variable is the same.Try to use a list (an object indexed by
foodId
, for example) of counts, like this:and in you jsx:
This should make it work as expected.
Note that there are some better ways to do it, like break into smaller components. As you learn more React it will probably become clearer to you. So, keep improving! 🙂
But for now, i hope this answer can help you unstuck and make progress on your work.