useState 随机设置状态

问题描述 投票:0回答:1

我的 useState 表现得很奇怪。

设置是这样的

  const [serviceDetails, setServiceDetails] = useState({ ...route.params });

当我在主函数中的任何位置调用

console.log(serviceDetails)
时,每次进行调整时我都可以看到状态变化。

这就是奇怪的地方。我有一个函数可以获取 serviceDetails 并将其发送到我的服务器进行保存。这里的控制台日志显示旧数据。


console.log(serviceDetails) < --- This shows correct data after being changed



async function saveService() {
    const location = await AsyncStorage.getItem("locationData");
    const parsedLocation = JSON.parse(location);




    console.log(serviceDetails); < ---this shows the wrong data, it displays the contents from the initial setup




    axios
      .post("http://localhost:7272/api/location/update-service", {
        _id: parsedLocation._id,
        service: serviceDetails,
      })
      .then((res) => {
        if (res.data.status == "success") {
          AsyncStorage.setItem(
            "locationData",
            JSON.stringify(res.data.data)
          ).then(() => {
            navigation.navigate("Edit Services", {
              location: res.data.data,
            });
          });
        } else {
          alert("There was an error saving the service");
        }
      })
      .catch((err) => {
        alert(err);
      });
  }

saveService 函数内部的控制台日志应该显示

{"concerns": ["Discolor", "Looser Skin", "Wellness", "Wrinkles"]}

但它却显示了

{"concerns": ["Discoloration", "Loose Skin", "Wellness", "Wrinkles"]}

完整代码在这里 您可以使用此对象代替route.params

{"_id": "66c4cc65fbcbee518050617e", "concerns": ["Discoloration", "Loose Skin", "Wellness", "Wrinkles"], "details": "This is details", "image": "", "name": "IPL Laser", "tags": [""], "treatment_plans": []}

import React, { useEffect, useState } from "react";
import {
  View,
  Text,
  TextInput,
  StyleSheet,
  Button,
  TouchableOpacity,
  ScrollView,
  Image,
} from "react-native";
import * as ImagePicker from "expo-image-picker";
import axios from "axios";
import AsyncStorage from "@react-native-async-storage/async-storage";

export default function EditService({ navigation, route }) {
  const [serviceDetails, setServiceDetails] = useState(route.params);

  const pickImageAsync = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      setServiceDetails({ ...serviceDetails, image: result.assets[0].uri });
    } else {
      alert("You did not select any image.");
    }
  };

  async function saveService() {
    const location = await AsyncStorage.getItem("locationData");
    const parsedLocation = JSON.parse(location);

    console.log(serviceDetails);

    axios
      .post("http://localhost:7272/api/location/update-service", {
        _id: parsedLocation._id,
        service: serviceDetails,
      })
      .then((res) => {
        if (res.data.status == "success") {
          AsyncStorage.setItem(
            "locationData",
            JSON.stringify(res.data.data)
          ).then(() => {
            navigation.navigate("Edit Services", {
              location: res.data.data,
            });
          });
        } else {
          alert("There was an error saving the service");
        }
      })
      .catch((err) => {
        alert(err);
      });
  }

  useEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <Button
          onPress={() => {
            saveService();
          }}
          title="Save"
        />
      ),
    });
  }, []);

  console.log(serviceDetails);

  return (
    <ScrollView
      contentContainerStyle={{
        gap: 20,
        padding: 10,
        backgroundColor: "lightgrey",
        paddingBottom: 100,
      }}
      showsVerticalScrollIndicator={false}
    >
      <View style={[styles.inputRow]}>
        <Text style={[styles.inputRowTitle]}>Name</Text>
        <TextInput
          style={[styles.input]}
          placeholder={route.params.name}
          onChangeText={(e) => {
            setServiceDetails({ ...serviceDetails, name: e });
          }}
        />
      </View>
      <View style={[styles.inputRow]}>
        <Text style={[styles.inputRowTitle]}>Details</Text>
        <TextInput
          style={[styles.input]}
          placeholder={route.params.details}
          onChangeText={(e) => {
            setServiceDetails({ ...serviceDetails, details: e });
          }}
        />
      </View>
      <View style={[styles.inputRow]}>
        <Text style={[styles.inputRowTitle]}>Image</Text>
        <Image
          source={{
            uri: serviceDetails.image || "https://via.placeholder.com/150",
          }}
          style={{
            width: "100%",
            aspectRatio: 16 / 9,
            backgroundColor: "white",
          }}
        />
        <TouchableOpacity
          style={styles.button}
          onPress={() => {
            pickImageAsync();
          }}
        >
          <Text style={[styles.inputRowTitle]}>Change Image</Text>
        </TouchableOpacity>
      </View>
      <View style={[styles.inputRow]}>
        <Text style={[styles.inputRowTitle]}>Treatment Plans</Text>
        <Text>Add your treatment plan options with pricing here</Text>
        {serviceDetails.treatment_plans.map((plan, index) => {
          return (
            <TextInput
              key={index}
              style={[styles.input]}
              placeholder={plan}
              onChangeText={(e) => {
                setServiceDetails({
                  ...serviceDetails,
                  treatment_plans: [
                    ...serviceDetails.treatment_plans.slice(0, index),
                    e,
                    ...serviceDetails.treatment_plans.slice(index + 1),
                  ],
                });
              }}
            />
          );
        })}
        <TouchableOpacity
          style={styles.button}
          onPress={() => {
            setServiceDetails({
              ...serviceDetails,
              treatment_plans: [...serviceDetails.treatment_plans, ""],
            });
          }}
        >
          <Text style={[styles.inputRowTitle]}>Add treatment plan</Text>
        </TouchableOpacity>
      </View>
      <View style={[styles.inputRow]}>
        <Text style={[styles.inputRowTitle]}>Treated Concerns</Text>
        {serviceDetails.concerns.map((concern, index) => {
          return (
            <TextInput
              key={index}
              style={[styles.input]}
              placeholder={concern}
              onChangeText={(e) => {
                setServiceDetails({
                  ...serviceDetails,
                  concerns: [
                    ...serviceDetails.concerns.slice(0, index),
                    e,
                    ...serviceDetails.concerns.slice(index + 1),
                  ],
                });
              }}
            />
          );
        })}
        <TouchableOpacity
          style={styles.button}
          onPress={() => {
            setServiceDetails({
              ...serviceDetails,
              concerns: [...serviceDetails.concerns, ""],
            });
          }}
        >
          <Text style={[styles.inputRowTitle]}>Add another concern</Text>
        </TouchableOpacity>
      </View>
      <View style={[styles.inputRow]}>
        <Text style={[styles.inputRowTitle]}>Tags</Text>
        <Text>Add tags to help categorize this service</Text>
        {serviceDetails.tags.map((tag, index) => {
          return (
            <TextInput
              key={index}
              style={[styles.input]}
              placeholder={tag}
              onChangeText={(e) => {
                setServiceDetails({
                  ...serviceDetails,
                  tags: [
                    ...serviceDetails.tags.slice(0, index),
                    e,
                    ...serviceDetails.tags.slice(index + 1),
                  ],
                });
              }}
            />
          );
        })}
        <TouchableOpacity
          style={styles.button}
          onPress={() => {
            setServiceDetails({
              ...serviceDetails,
              tags: [...serviceDetails.tags, ""],
            });
          }}
        >
          <Text style={[styles.inputRowTitle]}>Add another tag</Text>
        </TouchableOpacity>
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  inputRow: {
    gap: 5,
    padding: 10,
    backgroundColor: "white",
    borderRadius: 5,
  },
  inputRowTitle: {
    fontSize: 18,
    marginBottom: 5,
  },
  input: {
    backgroundColor: "rgb(240,240,240)",
    padding: 10,
    borderRadius: 5,
  },
  button: {
    backgroundColor: "#FFDBDD",
    padding: 10,
    borderRadius: 5,
    textAlign: "center",
    justifyContent: "center",
    alignItems: "center",
    alignContent: "center",
  },
});
reactjs react-native
1个回答
0
投票

使用Navigation.setOptions保存函数的整个状态,包括serviceDetails的初始状态。我想最好使用导航栏中的按钮进行导航。嗯,这不是猜测,这就是它的工作原理。

相反,我需要在 Scrollview 中创建一个新按钮并从那里调用 saveService。

© www.soinside.com 2019 - 2024. All rights reserved.