In short, worked quietly, but then wrote a couple of lines of code for an image that is not even related to useState just broke, other pages use the same methods as here, but they work there. I can’t explain exactly why this happens, probably due to repetition, where the first time it turns out to change the value, but then the second time it goes back to the standard value. I made this conclusion only because of the repetition in the console when I change the meaning in the text.
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>
)
}
I tried removing function call retry using useState, which checks for function dispatches and also useEffect, useTimeout, but they didn’t help anywhere close. I then started thinking about using useEffect to call 2 functions when running the page, I thought it was because of them, but even after deleting useEffect, nothing changed. And, unfortunately, apart from these assumptions, there were no others.