设置状态需要双击

set state required double click

我有一个 useState 挂钩,用于存储是否应显示菜单,在我的 jsx 渲染器中,我有一个 touchableOpacity,当我更改它时,它应该更新我的状态并显示菜单,但状态不更新,除非我给它点击不止一次 touchable。

在 showExpenses 函数中更新 expenseActivitie 状态时会发生此错误。

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 />
                }
        </>

    )
}

感谢任何帮助

setExpenseActivitie( prev => {
            ...prev,
            showExpense: !expenseActivitie.showExpense,
            currentIndex: index
        })

尝试修改您的 showexpenses 函数以使其看起来像这样。