总之,默默地工作,但后来为一个甚至与 useState 无关的图像编写了几行代码,刚刚崩溃,其他页面使用与这里相同的方法,但它们在那里工作。我无法确切解释为什么会发生这种情况,可能是由于重复,第一次结果改变了值,但第二次又回到了标准值。我做出这个结论只是因为当我更改文本中的含义时控制台中出现重复。
function CreateProduct({ navigation }) {
const [error, setError] = useState("");
const [categories, setCategories] = useState([])
const [loading, setLoading] = useState(<TouchableOpacity style={styles.button} onPress={()=>{handleSubmit()}}><Text style={styles.buttonText}>Створити</Text></TouchableOpacity>)
const [image, setImage] = useState("https://img.icons8.com/material-outlined/96/add-image.png");
const [data, setData] = useState({
name: "",
price: "",
description: "",
category: 0
});
function handleChange(name, value) {
setData((prevState) => ({...prevState,[name]: value,}))
}
async function getProfile() {
fetch(`${url}/user`,{
method: "GET",
headers: {
"apikey": await AsyncStorage.getItem('apikey')
}
})
.then(response => response.json())
.then(data => {
if (data.data.length <= 0 || data.error) {
navigation.navigate('Login')
}
})
.catch(error => {
navigation.navigate('Login')
})
}
function getCategories(){
fetch(`${url}/categories`,{
method: "GET"
})
.then(response => response.json())
.then(data => {
setCategories(data.categories)
})
}
async function handleSubmit() {
setError("")
if (!data.name){
setError("Enter a name")
return
}
if (!data.price){
setError("Enter a price")
return
}
if (!data.description){
setError("Enter a desc")
return
}
if (data.category == 0){
setError("Choose a category")
return
}
if (image == "https://img.icons8.com/material-outlined/96/add-image.png"){
setError("Add an image")
return
}
fetch(`${url}/productMobile`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'token': await AsyncStorage.getItem('apikey')
},
body: JSON.stringify({
name: data.name,
price: data.price,
desc: data.description,
image: image,
cat: data.category
}),
})
.then(response => response.json())
.then(async data => {
if (data.error) {
setLoading(<TouchableOpacity style={styles.button} onPress={()=>{handleSubmit()}}>
<Text style={styles.buttonText}>Створити</Text>
</TouchableOpacity>)
setError("Error while uploading Image");
} else {
setError("")
navigation.navigate("Account")
}
})
}
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 0.5,
base64: true,
});
if (!result.cancelled) {
setImage(`data:${result.assets[0].mimeType};base64,${result.assets[0].base64}`);
} else {
setError("Не вдалося додати зображення")
}
};
useEffect(() => {
getCategories();getProfile()
}, [])
return(
<View style={styles.containerShop}>
<View style={{backgroundColor: '#7F27FF', width: '100%', height: 70, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{color: 'white', fontSize: 30, fontWeight: 'bold'}}>Створення</Text>
</View>
<ScrollView style={{width: '100%'}}>
<View style={{alignItems: 'center', justifyContent: 'center', marginTop: 20, marginBottom: 20}}>
<TouchableOpacity onPress={pickImage}>
<Image style={styles.uploadImg} source={{ uri: image}}/>
</TouchableOpacity>
<View>
<Text style={styles.inputLabel}>Ім'я товару</Text>
<TextInput
style={styles.input}
onChangeText={(value) => {handleChange('name',value)}}
placeholder=" ..."
value={data.name}
/>
</View>
<View>
<Text style={styles.inputLabel}>Ціна товару</Text>
<TextInput
style={styles.input}
onChangeText={(value) => {handleChange('price',value)}}
placeholder=" ..."
keyboardType="numeric"
value={data.price}
/>
</View>
<View style={{width: "90%", marginTop: 10, marginBottom: 10}}>
<Text style={styles.inputLabel}>Категорія</Text>
<View style={styles.picker}>
<RNPickerSelect value={data.category} onValueChange={(value) => {handleChange('category',value)}}
items={categories && categories.map(item => ({label: item.name, value: item.id}))} />
</View>
</View>
<View>
<Text style={styles.inputLabel}>Опис</Text>
<TextInput
style={styles.inputDesc}
value={data.description}
onChangeText={(value) => {handleChange('description',value)}}
placeholder=" ..."
/>
</View>
<Text style={styles.error}>{error}</Text>
{loading}
</View>
</ScrollView>
<View style={styles.footer}>
<TouchableOpacity style={{flexDirection: 'column', alignItems: 'center'}} onPress={()=>{navigation.navigate('Main')}}>
<Image source={require('./assets/home.png')} style={{width: 40, height: 40}}/>
<Text style={{fontSize: 18, fontWeight: 'bold', color: 'white'}}>Головна</Text>
</TouchableOpacity>
<TouchableOpacity style={{flexDirection: 'column', alignItems: 'center'}} onPress={()=>{navigation.navigate('CreateProduct')}}>
<Image source={require('./assets/add.png')} style={{width: 40, height: 40}}/>
<Text style={{fontSize: 18, fontWeight: 'bold', color: 'white'}}>Створити</Text>
</TouchableOpacity>
<TouchableOpacity style={{flexDirection: 'column', alignItems: 'center'}} onPress={()=>{navigation.navigate('Account')}}>
<Image source={require('./assets/user.png')} style={{width: 40, height: 40}}/>
<Text style={{fontSize: 18, fontWeight: 'bold', color: 'white'}}>Акаунт</Text>
</TouchableOpacity>
</View>
</View>
)
}
我尝试使用 useState 删除函数调用重试,它检查函数调度以及 useEffect、useTimeout,但它们对任何地方都没有帮助。然后我开始考虑在运行页面时使用useEffect调用2个函数,我认为这是因为它们,但即使删除useEffect后,也没有任何改变。而且,不幸的是,除了这些假设之外,没有其他的。
考虑到您导入了 useState 并在函数组件中使用它。 我认为您代码中的问题是您尝试为 loading 状态提供默认 jsx 元素,但建议您可以将其初始化为 false,然后在获取数据时将其设置为 true,然后将其设置回 false 一次数据已获取。
const [loading, setLoading] = useState(false);
return (
<View style={styles.containerShop}>
{/* Your JSX content */}
</View>
);