skip to Main Content

I am trying to create a poll voting page where clicking on one of the options should increase its count by 1.

Here is what I have so far:

import { useState } from "react";
import { FlatList, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import FontAwesome from "react-native-vector-icons/FontAwesome"

export function PollDetailsScreen({ route }) {
    const { pollQuestion, pollOptions } = route.params;
    const [pollOptionState, setPollOptionState] = useState(pollOptions)

    const handleOptionClick = (key) => {
        setPollOptionState(prevOption => prevOption.map(
            opt => (opt.key === key ? opt.optionCount = opt.optionCount + 1 : opt)
        ))
    }

    const renderItem = ({ item }) => {
        return (
            <TouchableOpacity
                onPress={() => {
                    handleOptionClick(item.key)
                }}
                style={{ paddingTop: 32 }}
            >
                <View style={styles.item}>
                    <Text style={{ fontSize: 20 }}>{item.newOption}</Text>
                    <Text>{item.optionCount} vote{item.optionCount > 1 ? 's' : ''}  <FontAwesome name="check-circle" size={24} color="#617A67" /></Text>
                </View>
            </TouchableOpacity>
        );
    }

    return (
        <View style={styles.container}>
            <Text style={{ fontSize: 24 }}>{pollQuestion}</Text>
            <SafeAreaView>
                <FlatList
                    data={pollOptionState.sort((a, b) => b.optionCount - a.optionCount)}
                    renderItem={renderItem}
                    keyExtractor={item => item.key}
                    extraData={pollOptionState} />
            </SafeAreaView>
        </View>
    )
}

The pollOptions array of objects looks something like this:

pollOptions: [
  {
    key: "839f2h9",
    newOption: "Pasta",
    optionCount: 0
  },
  {
    key: "1v1wuw1",
    newOption: "Pizza",
    optionCount: 0
  },
  {
    key: "95823hc",
    newOption: "Kebab",
    optionCount: 0
  }
]

Here is a visualisation of what I have so far:
enter image description here

EDIT:
Right now, the issue I am facing is clicking on one of the options does not update Flatlist as it should. What am I doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    Found the solution to my problem, in the handleOptionClick function, I was trying to assign the value with the 'equal' sign instead of a 'colon'.

    This fixes the issue and updates the list upon clicking:

    const handleOptionClick = (key) => {
            setPollOptionState(prevOption => prevOption.map(
                opt => {
                    if (opt.key === key) {
                        return {
                            ...opt,
                            optionCount: opt.optionCount + 1
                        }
                    }
                    return opt;
                }
            ))
        }
    

  2. You need to put pollOptions and pollQuestions in a useState because you want its changes to cause a re-render.

    const [pollOptionsState,setPollOptionsState] = useState(pollOptions)
    const [pollQuestionsState,setPollQuestionsState] = useState(pollQuestions)
    

    updating it

    setPollOptionsState (prev => {
     // do logic here
     const newOpts = prev.filter(x=>...)
     return newOpts
    })
    

    OR, you can do setPrams

    const navigation = useNavigation()
    const update () => {
     navigation.setParams(...)
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search