marko
marko

Reputation: 2094

React Native: Flatlist rendered component state renders wrong data?

A bit hard to explain, so I have this flat list,

      <FlatList
        _light={{ bg: "gray.200" }}
        _dark={{ bg: "gray.900" }}
        data={data}
        refreshing={isLoading}
        onRefresh={loadData}
        renderItem={({item})=>(
          <ActivityCard
            data={item}
            onDeleted={()=>(console.log('delete'))}
            onUpdated={()=>(console.log('updated'))}
          />
        )}
        ListEmptyComponent={() => {
          return(
            <Center flex={1} height={window.height - tabHeight*2}>
              <Icon as={MaterialCommunityIcons} name='calendar-clock-outline' size={'3xl'} m={5} />
              <Text>Belum ada aktivitas</Text>
            </Center>
          );
        }}
      />

Relatively basic, but the issue is in the ActivityCard component

export default function ActivityCard({data, onUpdated, onDeleted}: prop) {
  const [bid, setBid] = useState(data.BiddingPrice + data.BidMultiplier);
  const [isDeleting, setIsDeleting] = useState(false);

  const textColor = useColorModeValue("black", "white");
  const bgColor = useColorModeValue("white", "#292524");

  console.log(`${data.BiddingPrice} + ${data.BidMultiplier} = ${data.BiddingPrice + data.BidMultiplier} -- ${bid}`)

  return (
    <VStack flex={1} mx={4} mt={6} shadow={2} borderWidth={1} p={2} borderRadius={'md'}
      _light={{ borderColor: "gray.300", bg: "gray.100" }}
      _dark={{ borderColor: "gray.700", bg: "gray.700" }}
    >
      
        <HStack mt={2} space={4} height={'36px'}>
          <HStack flex={1}>
            <IconButton variant={'outline'} colorScheme={'purple'}
              _icon={{ as: Entypo, name: "minus" }}
              onPress={() => {
                setBid(bid - data.BidMultiplier);
              }}
            />
            <MaskInput
              value={bid.toString()}
              keyboardType={'number-pad'}
              mask={dollarMask}
              style={{
                flex: 1, padding: 5, textAlign: 'center', backgroundColor: bgColor, color: textColor,
                borderTopColor: 'gray', borderTopWidth: 1, borderBottomColor: 'gray', borderBottomWidth: 1
              }}
              onChangeText={(masked, unmasked) => {
                setBid(parseInt(unmasked));
              }}
            />
            <IconButton variant={'outline'} colorScheme={'purple'}
              _icon={{ as: Entypo, name: "plus" }}
              onPress={() => {
                setBid(bid + data.BidMultiplier);
              }}
            />
          </HStack>
          <Button flex={1/4} size={'xs'}
            onPress={() => {
              (async () => {
                const {data: resp} = await api.addBid(data.ID, bid);
                console.log(resp);
              })();
            }}
          >
            BID
          </Button>
        </HStack>
      
    </VStack>
  )
};

I've set the state to price to bid + multiplier, but the value is wrong after a few rows. The console log result:

 LOG  100000 + 10000 = 110000 -- 43000
 LOG  200000 + 10000 = 210000 -- 130000
 LOG  43000 + 3000 = 46000 -- 15000
 LOG  120000 + 10000 = 130000 -- 130000
 LOG  12500 + 2500 = 15000 -- 130000
 LOG  125000 + 5000 = 130000 -- 130000
 LOG  125000 + 5000 = 130000 -- 130000

How do I go about fixing this? Can I use states within rows of Flatlist?

Upvotes: 0

Views: 60

Answers (1)

marko
marko

Reputation: 2094

Ooof figured it out. Seems like I can't just set the value during initialization, so const [bid, setBid] = useState(data.BiddingPrice + data.BidMultiplier); is bad.

Need to set it up within useEffect, so something like:

const [bid, setBid] = useState(0);

useEffect(() => {
  setBid(data.BiddingPrice + data.BidMultiplier);
}, []);

And everything will work as expected. All the values are correct.

Upvotes: 0

Related Questions