I have a useState hook that stores if a menu should be shown or not, in my jsx render I have a touchableOpacity that when I change it, it should update my state and show the menu, but the state does not update unless I give it click more than once to the touchable.
this error happens with the expenseActivitie state, when updating it within the showExpenses function.
Screen:
import React, { useContext, useEffect, useState } from 'react'import { Dimensions, Text, TouchableOpacity, View } from 'react-native'import { StackScreenProps } from '@react-navigation/stack';import { RootStackParams } from '../../navigator/Navigator';import { commonStyles } from '../../styles/commonStyles';import { ThemeContext } from '../../contexts/theme/ThemeContext';import LinearGradient from 'react-native-linear-gradient';import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';import { faExclamationCircle, faFilter } from '@fortawesome/free-solid-svg-icons';import { ExpenseActivitiesRQ } from '../../interfaces/viatics/ExpenseActivitiesRQ';import { useActivities } from '../../hooks/viatics/useActivities';import { AuthContext } from '../../contexts/auth/AuthContext';import { FlatList, ScrollView } from 'react-native-gesture-handler';import { GActivities } from '../../interfaces/viatics/GActivities';import Icon from 'react-native-vector-icons/Ionicons'import Moment from 'moment';import { setStateActivity } from '../../helpers/viatics/setStateActivity';import { setStateColor } from '../../helpers/viatics/setStateColor';import { ExpensesScreen } from './ExpensesScreen';import { ActivityIndicator } from 'react-native';import { Col, Grid, Row } from 'react-native-easy-grid';import { activitiesStyles } from '../../styles/activitiesStyles';import { MenuActivity } from '../../components/viatics/menuActivity';import { GExpenses } from '../../interfaces/viatics/GExpenses';interface Props extends StackScreenProps<RootStackParams, 'ActivitiesListScreen'>{};export const ActivitiesListScreen = ( { route, navigation }: Props ) => { const { userData } = useContext( AuthContext ); const request: ExpenseActivitiesRQ = { IDUser: userData.IDUser, IDEntity: userData.IDEntityDefault, excludeImages: true }; const type = route.params.type; const { loading, activitiesList } = useActivities( type, request ); const { theme: { colors, secondary, buttonText } } = useContext( ThemeContext ); const [expenseActivitie, setExpenseActivitie] = useState({ showExpense: false, currentIndex: -1 }); const [menus, setMenus] = useState({ menuExpense: false, menuActivity: false }); const [currentExpense, setCurrentExpense] = useState({ menuExpense: false, data: new GExpenses() }); useEffect(() => { switch( type ) { case 'allActivities': navigation.setOptions({ title: 'Actividades Generales' }); break; case 'pendingApprove': navigation.setOptions({ title: 'Pendientes por Aprobar' }); break; case 'pendingLegalize': navigation.setOptions({ title: 'Pendientes por Legalizar' }); break; default: navigation.setOptions({ title: 'Activitidades' }); break; } }, []); const renderActivitieCard = ( activitie: GActivities, index: number ) => { const bottomPadding: number = ( activitiesList.ListActivities.length === ( index + 1 ) && ( menus.menuActivity || menus.menuExpense ) ) ? 80 : 0; return (<> <View style={{ paddingBottom: bottomPadding }}> <View style={{ ...activitiesStyles.datesContainer, backgroundColor: colors.primary,}}><Text style={{ color: buttonText, fontSize: 12, marginLeft: 4 }}> { Moment(activitie.DateSta).format('DD/MMMM/YYYY') }</Text><Icon name="repeat" color={ buttonText } size={ 30 } /><Text style={{ color: buttonText, fontSize: 12 }}> { Moment(activitie.DateEnd).format('DD/MMMM/YYYY') }</Text><View style={{ ...activitiesStyles.activityState, backgroundColor: setStateColor(activitie.State) }}><Text style={{ textAlign: 'center', color: buttonText }}>{ setStateActivity(activitie.State) }</Text></View></View> <View style={{ borderWidth: 2, marginBottom: 10, borderColor: colors.primary, borderBottomLeftRadius: 10, borderBottomRightRadius: 10 }}><View style={{ marginTop: 10, marginBottom: 5 }}><View style={{ ...activitiesStyles.dataContainer, }}><Text style={{color: colors.text, fontWeight: 'bold'}}>Pasajero: </Text><Text style={{color: colors.text}}>{ activitie.UserName }</Text></View><View style={{ ...activitiesStyles.dataContainer }}><Text style={{color: colors.text, fontWeight: 'bold'}}>Actividad: </Text><Text style={{color: colors.text}}>{ activitie.Description }</Text></View><View style={{ ...activitiesStyles.dataContainer }}><Text style={{color: colors.text, fontWeight: 'bold'}}>Gastos Registrados: </Text><Text style={{color: colors.text}}>{ activitie.countExpenses }</Text></View><View style={{ ...activitiesStyles.dataContainer }}><Text style={{color: colors.text, fontWeight: 'bold'}}>Registrado: </Text><Text style={{color: colors.text}}>{ activitie.totalExpense } de { activitie.Budget } </Text></View><View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-around' }}><TouchableOpacity onPress={ () => showExpenses(index) } style={{ ...commonStyles.entireButton, }}><LinearGradient colors={[colors.primary, secondary]} style={ commonStyles.smallButton }><Text style={[commonStyles.buttonText, { color: buttonText }]}> Ver Gastos </Text></LinearGradient></TouchableOpacity><TouchableOpacity onPress={ () => navigation.navigate('RegisterExpensesScreen') } style={{ ...commonStyles.entireButton, }}><LinearGradient colors={[colors.primary, secondary]} style={ commonStyles.smallButton }><Text style={[commonStyles.buttonText, { color: buttonText }]}> Adicionar Gasto </Text></LinearGradient></TouchableOpacity><TouchableOpacity onPress={ () => setMenus({ ...menus, menuActivity: !menus.menuActivity })} style={{ ...commonStyles.entireButton, }}><LinearGradient colors={[colors.primary, secondary]} style={ commonStyles.smallButton }><Text style={[commonStyles.buttonText, { color: buttonText }]}> + Opciones </Text></LinearGradient></TouchableOpacity></View> { (expenseActivitie.showExpense === false && expenseActivitie.currentIndex === index ) &&<ExpensesScreen currentActivity={ activitie } menus={ menus } parentCallBack= { handleCallBack } /> }</View></View></View></> ) } const showExpenses = (index: number) => { setExpenseActivitie({ ...expenseActivitie, showExpense: !expenseActivitie.showExpense, currentIndex: index }) } const handleCallBack = (childData: GExpenses) => { console.log('childData', childData); setCurrentExpense({ ...currentExpense, data: childData, menuExpense: true, }) } return (<><View style={{ ...commonStyles.container, alignItems: 'stretch', bottom: 50, }}><Text style={{ ...commonStyles.title, color: colors.primary, marginBottom: 10 }}> Actividades de Gastos</Text><View style={ commonStyles.rightButtonContainer }><TouchableOpacity disabled={( activitiesList.ListActivities.length > 0) ? false : true } onPress={ () => navigation.navigate('FilterActivitiesScreen') } style={commonStyles.rightButton}><LinearGradient colors={[colors.primary, secondary]} style={{ ...commonStyles.rightButton, flexDirection: 'row' }}><FontAwesomeIcon style={{ color: buttonText }} icon={ faFilter } size={20} /><Text style={[commonStyles.buttonText, { color:'#fff' }]}>Filtrar</Text></LinearGradient></TouchableOpacity></View> { !loading &&<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><ActivityIndicator size="large" animating={ true } color={ colors.primary }></ActivityIndicator></View> } { ( loading && activitiesList.ListActivities.length > 0 ) &&<View style={{ marginTop: 10, flex: 1, width: '100%' }}><FlatList data={ activitiesList.ListActivities } keyExtractor={ (activie: GActivities) => activie.IDGroup } renderItem={ ({ item, index }) => renderActivitieCard( item, index ) } /></View> } { ( loading && activitiesList.ListActivities.length === 0 ) &&<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', }}><FontAwesomeIcon icon={ faExclamationCircle } color={ colors.primary } size={ 100 } /><Text style={{ ...commonStyles.title, fontSize: 25, color: colors.primary, marginBottom: 10 }}> No se encontraron Actividades</Text></View> } </View> { menus.menuActivity &&<MenuActivity /> }</> )}
I appreciate any help