繁体   English   中英

为什么我的 useState 值会在 onPress 方法中重置?

[英]Why does my useState value reset in onPress method?

我在我的本机反应组件中使用了一个名为 tripState 的 useState。

const [tripState, setTripState] = useState<NewTripState>({
    name: "",
    description: "",
    thumbnail: "",
});

我使用 function 在文本字段中更改其值:

const onChange = (
    key: keyof NewTripState,
    value: string | null,
): void => {
    setTripState({
        ...tripState,
        [key]: value,
    });
};

文字输入:

<TextInput
    value={tripState.name}
    onChangeText={(value: string): void => {
        onChange("name", value);
    }}
    placeholder={"Enter trip name"}
/>

在文本输入时调用。 如果我 console.log 中的值:

useEffect(() => {
    console.log(tripState); // console.logs updated state
}, [tripState]);

它控制台记录正确的(更新的)值,但是当我尝试在我的onSubmit方法中控制台记录它时,该方法在Pressable上的onPress上调用,我得到了初始值。

<Pressable onPress={onSubmit}>
    <Text>Save</Text>
</Pressable>
const onSubmit = () => {
    console.log(tripState); // console.logs initial state
};

有人可以帮帮我吗? 我不知道该怎么做了。

编辑 1:整个组件:

import React, { useEffect, useState } from "react";
import { useColorScheme } from "react-native";
import { getUserHoliday } from "../../api/firestore/trips";
import ProfilePicture from "../../components/ProfilePicture";
import {
    View,
    Text,
    Pressable,
} from "../../components/Themed";
import { tintColorLight } from "../../constants/Colors";
import store from "../../redux/store";
import { getUserId } from "../../redux/stores/user";
import { Holiday } from "../../utils/types/holiday";
import { Trip } from "../../utils/types/trip";

type NewTripScreenProps = {
    navigation: any;
    route: any;
};

export type NewTripState = {
    name: string;
    description: string;
    thumbnail: string;
};

const NewTripScreen = (props: NewTripScreenProps) => {
    const { navigation } = props;

    const [tripState, setTripState] = useState<NewTripState>({
        name: "",
        description: "",
        thumbnail: "",
    });

    useEffect(() => {
        console.log(tripState);
    }, [tripState]);

    const onChange = (
        key: keyof NewTripState,
        value: string | null,
    ): void => {
        setTripState((currentValue) => ({
            ...currentValue,
            [key]: value,
        }));
    };

    const userId = getUserId(store.getState());

    const colorScheme = useColorScheme();

    useEffect(() => {
        getUserHoliday(userId).then((holidays) => {
            setHolidays(holidays);
        });

        navigation.setOptions({
            headerTitle: "New Trip",
            headerRight: () => (
                <Pressable onPress={onSubmit}>
                    <Text
                        style={{
                            color: tintColorLight,
                            fontSize: 18,
                        }}
                    >
                        Save
                    </Text>
                </Pressable>
            ),
            headerTintColor: tintColorLight,
            headerTitleStyle: {
                color: colorScheme === "dark" ? "#fff" : "#000",
            },
        });
    }, []);

    const onSubmit = () => {
        console.log(tripState.name);

        const trip: Trip & { holiday?: Holiday | null } = {
            userId: userId,
            ...tripState,
            status: "created",
        };
    };

    return (
            <View>
                <Text
                    style={{
                        fontWeight: "bold",
                        fontSize: 32,
                        padding: 10,
                    }}
                >
                    New Trip
                </Text>
                <View style={{ alignItems: "center", marginTop: 20 }}>
                    <TextInput
                        value={tripState.name}
                        onChangeText={(value: string): void => {
                            onChange("name", value);
                        }}
                        placeholder={"Enter trip name"}
                    />

                    <TextInput
                        value={tripState.description}
                        onChangeText={(value: string): void => {
                            onChange("description", value);
                        }}
                        placeholder={"Enter Description"}
                        style={{ marginTop: 20 }}
                    />
                    <Text
                        style={{
                            fontWeight: "bold",
                            fontSize: 32,
                            padding: 10,
                        }}
                    >
                        Thumbnail
                    </Text>
                    <ProfilePicture
                        photoURL={tripState.thumbnail}
                        onPress={() => {}}
                    />
                </View>
            </View>
    );
};

export default NewTripScreen;

这是因为 useEffect 和空依赖数组而发生的。 当您在 Pressable 的 onPress 侦听器上添加onSubmit()时,由于 useEffect 具有空依赖数组,因此使用onSubmit内的 tripState 的原始值。

像这样更改代码

    useEffect(() => {
        getUserHoliday(userId).then((holidays) => {
            setHolidays(holidays);
        });

        navigation.setOptions({
            headerTitle: "New Trip",
            headerTintColor: tintColorLight,
            headerTitleStyle: {
                color: colorScheme === "dark" ? "#fff" : "#000",
            },
        });
    }, []);

  useEffect(() => {
       navigation.setOptions({
           headerRight: () => (
                <Pressable onPress={onSubmit}>
                    <Text
                        style={{
                            color: tintColorLight,
                            fontSize: 18,
                        }}
                    >
                        Save
                    </Text>
                </Pressable>
            )
           });
    }, [tripState]);


您要查找的主题称为“过时值”。 当值被锁定到您的 function 并且不刷新时,就会发生这种情况。 React useState 有办法解决这个问题,非常简单:

代替:

setTripState({
  ...tripState,
  [key]: value,
});

告诉 setState 你想使用最新的值:

setTripState(currentValue => ({
  ...currentValue,
  [key]: value,
}));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM