我的 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",
},
});
使用Navigation.setOptions保存函数的整个状态,包括serviceDetails的初始状态。我想最好使用导航栏中的按钮进行导航。嗯,这不是猜测,这就是它的工作原理。
相反,我需要在 Scrollview 中创建一个新按钮并从那里调用 saveService。